我们的一个流程包括将Excel电子表格复制粘贴到氧气编辑器文档中。它工作得很好,但不抓特殊字符,所以,我正在编写一个脚本来查找和更改它们。我已经开始在流模式下使用XML :: Parser,但是我不太确定我将如何使用这种方法获得我需要的地方。尝试编辑XML文档中的PCDATA
首先,因为解析器(正确)不关心属性顺序,所以属性可以(并且)以不同顺序返回,这会使一些人烦恼。另外,我目前还不能一致地识别PCDATA。而且,重新组装元素标签似乎有点多...而且我也不会很好地处理EMPTY元素。我在这里只是想念一下,还是应该看看别的东西,比如XML :: Twig?
在此先感谢所有需要回复的人(任何人)!
use strict;
use warnings;
use IO::File;
use XML::Parser;
my $xml = <<EOD;
<?xml version="1.0"?>
<messages>
<message>
<from id="t_8ur9k0" type="king">Maximus</from>
<to>knave</to>
<subject>My boots</subject>
<body>I <i>really</i> want my riding boots. Bring them to me, at once!</body>
</message>
</messages>
EOD
my $parser = new XML::Parser(Style => 'Stream', ErrorContext => 2);
$parser->setHandlers(Start => \&handle_start,
End => \&handle_end,
Char => \&handle_char,
Default => \&handle_default);
$parser->parse($xml);
sub handle_start {
my ($self, $tag, %attrs) = @_;
my $atts = '';
if (%attrs) {
while (my ($key, $val) = each(%attrs)) {
$atts .= " " . $key . '="' . $val . '"';
}
}
print "<" . $tag . $atts . ">";
}
sub handle_end {
my ($self, $tag) = @_;
print "</" . $tag . ">";
}
sub handle_char {
my ($self,$raw) = @_;
if (!($raw =~ m/\s/)) {
$raw =~ s/.*/FOO/;
}
print $raw;
}
sub handle_default {
my ($self,$str) = @_;
print $str;
}
啊,OK。我记得,XML解析器不需要遵守属性顺序,所以我认为这就是抛弃它们的原因。哈希也是这样做的。并且对于我之后不清楚的道歉:我想扫描PCDATA元素的内容并将特殊字符更改为实体;例如,将每个[±]更改为[±]。所以XPath将无法维护,每次更改DTD都要求我更新脚本。 – Greg 2012-03-27 11:58:33
@Greg:我没有看到问题。您可以使用'// text()'访问XML文档中的所有PCDATA。我已添加到我的答案中,以显示如何将所有文本节点设置为小写。 – Borodin 2012-03-27 14:28:56
我确实 - 我宣布XPath无法在再次查看之前帮助我。 (我学习和使用它已经有多年了。)我很抱歉打扰! – Greg 2012-03-27 15:05:14