プロセスの1つに、ExcelスプレッドシートからOxygenエディタ文書へのコピー・ペーストがあります。それはかなりうまくいくが、特殊文字を捕まえないので、私はそれらを見つけて変更するスクリプトを書いている。私はストリームモードで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
@Greg:問題は表示されません。 '// text()'を使って、XML文書内のすべてのPCDATAにアクセスできます。すべてのテキストノードを小文字に設定する方法を示すために、私の答えに追加しました。 – Borodin
私はXPathが再びそれを見て前に私を助けることができないと宣言しました。 (私はそれを勉強して使ってから何年も経っています)。 – Greg