2011-08-12 12 views
4

私はperlのXML :: LibXMLモジュールを使用して、デバイスからのXML応答を解析しています。 データを正常に取得できる唯一の方法は、デバイスからのXML応答を変更することです。perl XML :: LibXMLを使用して解析する

#!/bin/env perl 
use strict; 
use warnings; 
use XML::LibXML; 
my $f = ("/var/working/xmlstuff"); 
sub yeah { 
my $ff; 
my $f = shift; 
open(my $fff,$f); 
while(<$fff>) { 
$_ =~ s/^\s+$//; 
$_ =~ s/^(<\S+)\s.*?=.*?((?:\/)?>)/$1$2/g; 
$ff .= $_; 
} 
close($fff); 
return $ff 
} 
my $tparse = XML::LibXML->new(); 
my $ss = $tparse->load_xml(string => &yeah($f)); 
print map $_->to_literal,$ss->findnodes('/chassis-inventory/chassis/serial-number'); 

私は正規表現置換を使用しない場合:ここでは

<chassis-inventory xmlns="http://xml.juniper.net/junos/10.3D0/junos-chassis"> 

<chassis junosstyle="inventory"> 

<name>Chassis</name> 

<serial-number>JN111863EAFF</serial-number> 

<description>VJX1000</description> 

<chassis-module> 

<name>Midplane</name> 

</chassis-module> 

<chassis-module> 

<name>System IO</name> 

</chassis-module> 

<chassis-module> 

<name>Routing Engine</name> 

<description>VJX1000</description> 

<chassis-re-disk-module> 

<name>ad0</name> 

<disk-size>1953</disk-size> 

<model>QEMU HARDDISK</model> 

<serial-number>QM00001</serial-number> 

<description>Hard Disk</description> 

</chassis-re-disk-module> 

</chassis-module> 

<chassis-module> 

<name>FPC 0</name> 

<chassis-sub-module> 

<name>PIC 0</name> 

</chassis-sub-module> 

</chassis-module> 

<chassis-module> 

<name>Power Supply 0</name> 

</chassis-module> 

</chassis> 

</chassis-inventory> 

は、私が解析し、例えばシリアル番号を確認するために使用していますPerlのコードです: は、ここにデバイスからの私のXML応答であります解析するスクリプトには何もロードされません。 私は改行のストリッピングを理解することができますが、これらの線場合にのみ動作しますので、なぜ私は、XML応答から属性を削除する必要があります:

<chassis-inventory> 
<chassis> 
  1. <chassis-inventory xmlns="http://xml.juniper.net/junos/10.3D0/junos-chassis"> 
    
    <chassis junosstyle="inventory"> 
    

    このなろ

    これはXMLレスポンスやXML :: LibXMLモジュールの問題ですか?

  2. 正規表現置換を使用せずにファイルに空の行があるという事実を無視する方法はありますか?

ありがとうございました。

+0

XMLに適切なヘッダーとdoctypeがないため、おそらく失敗していると思います。これは、XMLが100%正確でない場合でも、解析するために設定できるXML :: Simpleを試してみるほど簡単です。 – Cfreak

答えて

12

XPATH式が失敗した理由は、名前空間のためです。それに関連して検索する必要があります。ここでXML::libXML documentationからの説明です:名前空間とXPATH ON

注:

のXPathについてのよくある間違いは、デフォルト 名前空間の接頭辞なしのマッチ要素と要素名の からなるそのノード・テストを仮定することです。この仮定は間違っています。つまり、XPath仕様では、 ノードテストは、no(つまりnull)の要素にのみ一致します 名前空間。

ので、例えば、一つは$リンパ節転移とXHTML 文書のルート要素が一致することはできません>(「/ HTML」)を見つける ルート要素は名前空間がなかった場合は「/ htmlが」のみ一致するからであるが、すべてのXHTML要素 は、http://www.w3.org/1999/xhtmlという名前空間に属しています。 ( xmlns = "..."というネームスペース宣言は、XML文書がデフォルトのネームスペースがない場合は のように見えるので、状況を悪化させるDTDの でも指定できます。

これを処理するには、ネームスペースを登録し、ネームスペースを使用してドキュメントを検索します。

#!/bin/env perl 
use strict; 
use warnings; 
use XML::LibXML; 

my $xml = XML::LibXML->load_xml(location => '/var/working/xmlstuff'); 
my $xpc = XML::LibXML::XPathContext->new($xml); 
$xpc->registerNs('x', 'http://xml.juniper.net/junos/10.3D0/junos-chassis'); 

foreach my $node ($xpc->findnodes('/x:chassis-inventory/x:chassis/x:serial-number')) { 

    print $node->textContent() . "\n"; 
} 
+1

説明と解決策をありがとう。 – salparadise

関連する問題