Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 已解决:XPath:循环通过没有子节点和子节点的节点_Xml_Perl_Xpath_Xml Libxml - Fatal编程技术网

Xml 已解决:XPath:循环通过没有子节点和子节点的节点

Xml 已解决:XPath:循环通过没有子节点和子节点的节点,xml,perl,xpath,xml-libxml,Xml,Perl,Xpath,Xml Libxml,我使用XML::LibXML在perl中导入了一个XML文件。生成的XPath结构有几个节点。有些有孩子,有些没有。如何在没有子节点的所有节点之间循环,然后在有子节点的所有节点之间循环? 致以最良好的祝愿,丹尼尔 编辑:更多细节-2020-11-11 10:10 亲爱的,对不起,我的坏,我需要在这里更准确。 另外:新手提醒(以防你还没有注意到) 用例 我正在编写一个perl脚本,它将读取OneWire网关。几个传感器连接到网关。perl脚本从网关读取XML数据。XML数据包含网关的数据(如连接了

我使用XML::LibXML在perl中导入了一个XML文件。生成的XPath结构有几个节点。有些有孩子,有些没有。如何在没有子节点的所有节点之间循环,然后在有子节点的所有节点之间循环? 致以最良好的祝愿,丹尼尔

编辑:更多细节-2020-11-11 10:10

亲爱的,对不起,我的坏,我需要在这里更准确。 另外:新手提醒(以防你还没有注意到)

用例 我正在编写一个perl脚本,它将读取OneWire网关。几个传感器连接到网关。perl脚本从网关读取XML数据。XML数据包含网关的数据(如连接了多少设备、一个计数器和多个读数)。XML数据中还提供了每个连接传感器的读数(温度、湿度等)

XML数据 下面是一个XML的示例。我把它缩短了。读数的数量和传感器的数量可能会有所不同:

<?xml version="1.0" encoding="UTF-8"?>
<Devices-Detail-Response xmlns="http://www.embeddeddatasystems.com/schema/owserver" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PollCount>1069</PollCount>
<DevicesConnected>1</DevicesConnected>
<LoopTime>1.630</LoopTime>
<owd_DS18B20 Description="Programmable resolution thermometer">
<Name>DS18B20</Name>
<Family>28</Family>
<ROMId>60000003BDE03828</ROMId>
<Health>0</Health>
<Channel>1</Channel>
<RawData>000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</RawData>
<PrimaryValue>0.0000 Deg C</PrimaryValue>
<Temperature Units="Centigrade">0.0000</Temperature>
<UserByte1 Writable="True">0</UserByte1>
<UserByte2 Writable="True">0</UserByte2>
<Resolution>9</Resolution>
<PowerSource>0</PowerSource>
</owd_DS18B20>
<owd_DS18B20 Description="Programmable resolution thermometer">
<Name>DS18B20</Name>
<Family>28</Family>
<ROMId>73000003BDD96528</ROMId>
<Health>0</Health>
<Channel>1</Channel>
<RawData>000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</RawData>
<PrimaryValue>0.0000 Deg C</PrimaryValue>
<Temperature Units="Centigrade">0.0000</Temperature>
<UserByte1 Writable="True">0</UserByte1>
<UserByte2 Writable="True">0</UserByte2>
<Resolution>9</Resolution>
<PowerSource>0</PowerSource>
</owd_DS18B20>
<owd_DS2423 Description="RAM with counters">
<Name>DS2423</Name>
<Family>1D</Family>
<ROMId>100000000FCB421D</ROMId>
<Health>0</Health>
<Channel>1</Channel>
<RawData>000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</RawData>
<PrimaryValue>0, 0</PrimaryValue>
<Counter_A>0</Counter_A>
<Counter_B>0</Counter_B>
</owd_DS2423>
<owd_DS2423 Description="RAM with counters">
<Name>DS2423</Name>
<Family>1D</Family>
<ROMId>F10000000F88251D</ROMId>
<Health>0</Health>
<Channel>1</Channel>
<RawData>000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</RawData>
<PrimaryValue>0, 0</PrimaryValue>
<Counter_A>0</Counter_A>
<Counter_B>0</Counter_B>
</owd_DS2423>
</Devices-Detail-Response>
为什么要更改它? 我希望有一种更通用的方法,而不预先指定我期望的节点(基本上省略两个qw数组)

我希望这一点现在更清楚了。感谢您的帮助! 致以最良好的祝愿,丹尼尔

编辑:这里有一个似乎很有效的解决方案:

#!/usr/bin/env perl
use warnings;
use strict;
use autodie;
use feature 'say';
use XML::LibXML;
use XML::LibXML::XPathContext;
use Readonly;

Readonly my $url => 'details.xml'; # This is the XML file
#Readonly my $url => 'http://192.168.0.73/details.xml';
my $xmlns = 'http://www.embeddeddatasystems.com/schema/owserver';
Readonly my $ns => 'ow';

say "My source is $url";

my $dom = eval {
    XML::LibXML->load_xml(location => $url);
};
if($@) {
    # Log failure and exit
    say "Error parsing $url";
    say "$@";
    say 'I will exit now.';
    exit 0;
}

say "XML::LibXML has read $url";
#say $dom;
say '';

my $xpath = XML::LibXML::XPathContext->new($dom);
$xpath->registerNs($ns, $xmlns); 

say 'Process xpath doc in a nested loop';
say 'Outer loop: to iterate through all nodes with children (i.e. parents).';
say 'Inner loop: loop through the found parents and filter for children that have no children themselves.';
foreach my $node ($xpath->findnodes("//$ns:*[count(*)>0]")) { # only parents are found
    say $node->localname;
    foreach my $child ($node->findnodes("*[count(*)=0]")) { # parents are excluded
        next if ($child->localname eq 'RawData');
        say '   ' . $child->localname . ' = ' . $child->to_literal;
    }
}
say'';

请编辑你的问题,并提供一个最小的可复制的例子。我们真的应该看到一些细节。你能发布这样一个文件的简短示例和你拥有的代码(工作与否)吗?
/*[count(*)>0]
/*[count(*)=0]
,我想。但是,这只查找作为元素的子元素。这是
//子元素::*
还是只查找终端节点?请澄清。好的,我自己找到了解决办法。//*[count(*)>0]表达式为我指明了正确的方向。我已经将我的新代码包含在我的提问中。请编辑您的问题并提供一个最小的可复制示例。我们真的应该看到一些细节。你能发布这样一个文件的简短示例和你拥有的代码(工作与否)吗?
/*[count(*)>0]
/*[count(*)=0]
,我想。但是,这只查找作为元素的子元素。这是
//子元素::*
还是只查找终端节点?请澄清。好的,我自己找到了解决办法。//*[count(*)>0]表达式为我指明了正确的方向。我已经在我的questoin中包含了我的新代码。
#!/usr/bin/env perl
use warnings;
use strict;
use autodie;
use feature 'say';
use XML::LibXML;
use XML::LibXML::XPathContext;
use Readonly;

Readonly my $url => 'details.xml'; # This is the XML file
#Readonly my $url => 'http://192.168.0.73/details.xml';
my $xmlns = 'http://www.embeddeddatasystems.com/schema/owserver';
Readonly my $ns => 'ow';

say "My source is $url";

my $dom = eval {
    XML::LibXML->load_xml(location => $url);
};
if($@) {
    # Log failure and exit
    say "Error parsing $url";
    say "$@";
    say 'I will exit now.';
    exit 0;
}

say "XML::LibXML has read $url";
#say $dom;
say '';

my $xpath = XML::LibXML::XPathContext->new($dom);
$xpath->registerNs($ns, $xmlns); 

say 'Process xpath doc in a nested loop';
say 'Outer loop: to iterate through all nodes with children (i.e. parents).';
say 'Inner loop: loop through the found parents and filter for children that have no children themselves.';
foreach my $node ($xpath->findnodes("//$ns:*[count(*)>0]")) { # only parents are found
    say $node->localname;
    foreach my $child ($node->findnodes("*[count(*)=0]")) { # parents are excluded
        next if ($child->localname eq 'RawData');
        say '   ' . $child->localname . ' = ' . $child->to_literal;
    }
}
say'';