我正在使用XML::LibXML
解析XML文件。在訪問節點元素時使用註冊名稱空間似乎存在一些問題。我打算將這個XML數據轉換爲CSV文件。我試圖訪問這裏的每一個元素。首先,我嘗試提取<country>
和<state>
標籤的屬性值。以下是我帶的代碼。但我得到錯誤說XPath error : Undefined namespace prefix
。無法使用註冊命名空間解析xml文件
use strict;
use warnings;
use Data::Dumper;
use XML::LibXML;
my $XML=<<EOF;
<DataSet xmlns="http://www.w3schools.com" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com note.xsd">
<exec>
<survey_region ver="1.1" type="x789" date="20160312"/>
<survey_loc ver="1.1" type="x789" date="20160312"/>
<note>Population survey</note>
</exec>
<country name="ABC" type="MALE">
<state name="ABC_state1" result="PASS">
<info>
<type>literacy rate comparison</type>
</info>
<comment><![CDATA[
Some random text
contained here
]]></comment>
</state>
</country>
<country name="XYZ" type="MALE">
<state name="XYZ_state2" result="FAIL">
<info>
<type>literacy rate comparison</type>
</info>
<comment><![CDATA[
any random text data
]]></comment>
</state>
</country>
</DataSet>
EOF
my $parser = XML::LibXML->new();
my $doc = $parser->parse_string($XML);
my $xc = XML::LibXML::XPathContext->new($doc);
$xc->registerNs('x','http://www.w3schools.com');
foreach my $camelid ($xc->findnodes('//x:DataSet')) {
my $country_name = $camelid->findvalue('./x:country/@name');
my $country_type = $camelid->findvalue('./x:country/@type');
my $state_name = $camelid->findvalue('./x:state/@name');
my $state_result = $camelid->findvalue('./x:state/@result');
print "state_name ($state_name)\n";
print "state_result ($state_result)\n";
print "country_name ($country_name)\n";
print "country_type ($country_type)\n";
}
更新 如果我刪除從XML命名空間以及稍有改變我的XPath它似乎工作。有人能幫助我理解這種差異嗎?
foreach my $camelid ($xc->findnodes('//DataSet')) {
my $country_name = $camelid->findvalue('./country/@name');
my $country_type = $camelid->findvalue('./country/@type');
my $state_name = $camelid->findvalue('./country/state/@name');
my $state_result = $camelid->findvalue('./country/state/@result');
print "state_name ($state_name)\n";
print "state_result ($state_result)\n";
print "country_name ($country_name)\n";
print "country_type ($country_type)\n";
}
如果我刪除註冊的命名空間,並嘗試使用我的相同的代碼,它似乎工作。你能幫我理解差異嗎?已經更新了我的問題中的代碼。 – chidori
@chidori請看看更新。 –