gpt4 book ai didi

xml - Perl XML::LibXML 用法

转载 作者:数据小太阳 更新时间:2023-10-29 03:00:31 24 4
gpt4 key购买 nike

我在使用 XML::LibXML 时遇到了一些问题,我想知道是否有办法做我想做的事情,或者我的 XML 是否应该更改。

目前,我的 XML 看起来像:

<fftg>
<actions>

<rename>
<mandatory>0</mandatory>
<other_things_here />
</rename>

<transfer>
<mandatory>0</mandatory>
<protocol>SFTP</protocol>
<other_things_here />
</transfer>

<transfer>
<mandatory>1</mandatory>
<protocol>FTP</protocol>
<other_things_here />
</transfer>

<archive>
<mandatory>1</mandatory>
<other_things_here />
</archive>

<rename>
<mandatory>1</mandatory>
<other_things_here />
</rename>

</actions>

</fftg>

如您所见,在“ Action ”下,可以有不同类型的 Action (每种 Action 有一个或多个 Action ,每个 Action 下有不同的东西)

我想浏览每个 Action 并根据 Action 执行特定的事情。

我的问题是:由于有多个相同类型的 Action ,脚本无法正常工作并覆盖之前的相同类型 Action ,或者特定 Action 上的循环在每个相同类型的 Action 上重新循环

示例 1:

foreach my $transfer ($doc->findnodes('/fftg')) {

# Browse Actions
foreach my $action ($doc->findnodes('/fftg/actions/*')) {

my $action_name = $action->nodeName();
my $actiontype = ucfirst($action->nodeName());
print "executing action $action_name ..\n";

# Browse action details
foreach my $action_details ($doc->findnodes('/fftg/actions/'.$action_name)) {
for my $detail ($action_details->findnodes('./*')) {
print $detail->nodeName(), ": ", $detail->textContent(), "\n";
}
}
print "-------------\n";
}
}

结果 1:

executing action rename ..
mandatory: 0
other_things_here:
mandatory: 1
other_things_here:
-------------
executing action transfer ..
mandatory: 0
protocol: SFTP
other_things_here:
mandatory: 1
protocol: FTP
other_things_here:
-------------
executing action transfer ..
mandatory: 0
protocol: SFTP
other_things_here:
mandatory: 1
protocol: FTP
other_things_here:
-------------
executing action archive ..
mandatory: 1
other_things_here:
-------------
executing action rename ..
mandatory: 0
other_things_here:
mandatory: 1
other_things_here:
-------------

正如您所看到的,这个结果是错误的,因为在每个“ Action 类型”(这是好的,检测到的)中,它会在同类的每个 Action 上重新循环。

这是由于:

foreach my $action_details ($doc->findnodes('/fftg/actions/'.$action_name)) {

我该怎么做才能实现我想要的目标? (如果可能的话不改变 XML)

我想要的是:

executing action rename ..
mandatory: 0
other_things_here:
-------------
executing action transfer ..
mandatory: 0
protocol: SFTP
other_things_here:
-------------
executing action transfer ..
mandatory: 1
protocol: FTP
other_things_here:
-------------
executing action archive ..
mandatory: 1
other_things_here:
-------------
executing action rename ..
mandatory: 1
other_things_here:
-------------

谢谢

附带说明一下,我想我可以更改我的 XML 并使用类似的东西来轻松修复它(但我不知道哪一个是三者之间的最佳选择),但我想避免下面这两个是因为 XSD 之后很难生成(我想要每种操作类型的特定选项):

<fftg>
<actions>
<action>
<type>rename</type>
<mandatory>0</mandatory>
<other_things_here />
</action>

<action>
<type>transfer</type>
<mandatory>0</mandatory>
<protocol>SFTP</protocol>
<other_things_here />
<action>

<action>
<type>transfer</type>
<mandatory>0</mandatory>
<protocol>FTP</protocol>
<other_things_here />
<action>

<action>
<type>archive</type>
<mandatory>0</mandatory>
<other_things_here />
<action>

<action>
<type>rename</type>
<mandatory>0</mandatory>
<other_things_here />
<action>



</actions>

</fftg>

<fftg>
<actions>
<action type="rename">
<mandatory>0</mandatory>
<other_things_here />
</action>

<action type="transfer">
<mandatory>0</mandatory>
<protocol>SFTP</protocol>
<other_things_here />
<action>

<action type="transfer">
<mandatory>0</mandatory>
<protocol>FTP</protocol>
<other_things_here />
<action>

<action type="archive">
<mandatory>0</mandatory>
<other_things_here />
<action>

<action type="rename">
<mandatory>0</mandatory>
<other_things_here />
<action>



</actions>

</fftg>

再次感谢问候,

最佳答案

首先,您调用 findnodes$doc ,这意味着您的 XPath 表达式是根据文档根节点计算的。其次,您使用的 XPath 表达式以“/”开头,因此再次以顶级节点为根。这样,当您打电话时:

$doc->findnodes('/fftg/actions/rename')

它的意思是“给我每个 <rename/> 元素,它是 <actions/> 的子元素,<fftg/> 元素的子元素,它是文档的根节点”,结果,你得到每个 <rename/>在文档中找到的节点。

而且,循环太多了。第一个是多余的,因为可能只有一个根元素。两个循环应该可以工作(一个在 <action/> child 身上,另一个在他们的 child 身上):

for my $action ($doc->findnodes('/fftg/actions/*')) {
print "executing ", $action->nodeName(), "\n";
for my $detail ($action->findnodes('./*')) {
print $detail->nodeName(), ": ", $detail->textContent(), "\n";
}
}

关于xml - Perl XML::LibXML 用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44155750/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com