【发布时间】:2018-11-07 12:08:57
【问题描述】:
我正在尝试更改源 XML 文件中三个元素的文本。
两个目标具有相同的元素名称 (ifw6:value),但存在于不同的标题下。第三个的元素名称与前两个不同。
程序成功执行,但打印原始 XML 文件而不做任何修改。调试语句让我相信它没有执行映射在twig_handlers 中的子例程。
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my $text1 = "123456789";
my $text2 = "1234567";
my $text3 = "001";
my $twig = XML::Twig->new(
pretty_print => 'indented',
twig_handlers => {
text => sub {
my $targ1_2 = $_->next_elt('ifw6:value');
my $targ3 = $_->next_elt('ifw4:relationship');
if ($targ1_2->text eq 'target1') {
$targ1_2->set_text($text1);
}
if ($targ1_2->text eq 'target2') {
$targ1_2->set_text($text2);
}
if ($targ3->text eq 'target3') {
$targ3->set_text($text3);
}
$targ1_2->flush;
$targ3->flush;
}
}
);
$twig->parsefile('text.xml');
$twig->print();
文本.xml
<SOAP-ENV>
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ifw:Information>
<requestHeader>
<ifw1:id/>
</requestHeader>
<ifw4:Miscellaneous>
<ifw6:MiscVals xsi:type="type1">
<ifw6:value>target1</ifw6:value>
</ifw6:MiscVals>
<ifw6:MiscVals xsi:type="type2">
<ifw6:Vals xsi:type="type3">
<ifw6:value>target2</ifw6:value>
</ifw6:Vals>
</ifw6:MiscVals>
<ifw4:relationship>target3</ifw4:relationship>
</ifw4:Miscellaneous>
</ifw:Information>
</SOAP-ENV:Body>
</SOAP-ENV>
想要的结果
<SOAP-ENV>
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ifw:Information>
<requestHeader>
<ifw1:id/>
</requestHeader>
<ifw4:Miscellaneous>
<ifw6:MiscVals xsi:type="type1">
<ifw6:value>123456789</ifw6:value>
</ifw6:MiscVals>
<ifw6:MiscVals xsi:type="type2">
<ifw6:Vals xsi:type="type3">
<ifw6:value>1234567</ifw6:value>
</ifw6:Vals>
</ifw6:MiscVals>
<ifw4:relationship>001</ifw4:relationship>
</ifw4:Miscellaneous>
</ifw:Information>
</SOAP-ENV:Body>
</SOAP-ENV>
【问题讨论】:
-
您的
text正在寻找像<text>这样的元素,而不是文本节点。在 XPath 中,您将使用text(),但我不确定它是否适用于XML::Twig。 -
搜索
ifw6:value和ifw4:relationship并修改其文本内容。 -
正确的方法确实是在命名元素上使用
twig_handlers,正如@Borodin 所说。要触发文本处理程序,您需要使用“#TEXT”,如果您习惯于 CSS 选择器,这无疑会令人困惑,但这种语法实际上早于 CSS :--( -
@mirod:感谢您的确认。当然我应该记得
#TEXT,但是代码要检查$_->parent->tag,比较麻烦。虽然,考虑到这一点,我怀疑文本节点是否是XML::Twig::Elt对象,而且我无法进行实验。 -
@Borodin 一个文本节点是一个 XML::Twig::Elt 对象。为了使混合内容起作用,它必须这样做。它的标签“名称”是
#PCDATA(或#CDATA),尽管您不能在#PCDATA(IIRC)上拥有处理程序
标签: xml perl text-parsing