2013-04-24 61 views
1

我使用XML :: LibXML(僅限於v1.58)。 感謝Borodinthis後我正確得到PROPERTY NAME="Name"的值如果CLASSNAME="SharedGtTranslator"。 我會添加喜歡的是獲取包含上述提到的整個VALUE.OBJECT父元素,並將其輸出到另一個XML文件。使用Perl/LibXML獲取子元素匹配標準的XML父元素

因此,如果XML文件看起來像這樣:

<CIM CIMVERSION="2.0" DTDVERSION="2.0"> 

    <DECLARATION> 
    <DECLGROUP> 
     <LOCALNAMESPACEPATH> 
     <NAMESPACE NAME="ecm"/> 
     </LOCALNAMESPACEPATH> 

     <!-- Ecm --> 

     <VALUE.OBJECT> 
     <INSTANCE CLASSNAME="Ecm"> 
      <PROPERTY NAME="FileName" TYPE="string"> 
      <VALUE>/opt/sign/log/ecm.log</VALUE> 
      </PROPERTY> 
      <PROPERTY NAME="Log" TYPE="sint32"> 
      <VALUE>0</VALUE> 
      </PROPERTY> 
      <PROPERTY NAME="Name" TYPE="string"> 
      <VALUE>ECM</VALUE> 
      </PROPERTY> 
      <PROPERTY NAME="TimerClaim" TYPE="sint32"> 
      <VALUE>5000</VALUE> 
      </PROPERTY> 
      <PROPERTY NAME="TimerConnect" TYPE="sint32"> 
      <VALUE>8000</VALUE> 
      </PROPERTY> 
      <PROPERTY NAME="TimerNegotiate" TYPE="sint32"> 
      <VALUE>5000</VALUE> 
      </PROPERTY> 
      <PROPERTY NAME="TimerReconnect" TYPE="sint32"> 
      <VALUE>500</VALUE> 
      </PROPERTY> 
     </INSTANCE> 
     </VALUE.OBJECT> 

     <VALUE.OBJECT> 
     <INSTANCE CLASSNAME="Ecm_Host"> 
      <PROPERTY.REFERENCE NAME="Parent"> 
      <VALUE.REFERENCE> 
       <INSTANCENAME CLASSNAME="Ecm"> 
       <KEYBINDING NAME="Name"> 
        <KEYVALUE>ECM</KEYVALUE> 
       </KEYBINDING> 
       </INSTANCENAME> 
      </VALUE.REFERENCE> 
      </PROPERTY.REFERENCE> 
      <PROPERTY.REFERENCE NAME="Child"> 
      <VALUE.REFERENCE> 
       <INSTANCENAME CLASSNAME="Host"> 
       <KEYBINDING NAME="Address"> 
        <KEYVALUE>gtttcnss7v19</KEYVALUE> 
       </KEYBINDING> 
       </INSTANCENAME> 
      </VALUE.REFERENCE> 
      </PROPERTY.REFERENCE> 
     </INSTANCE> 
     </VALUE.OBJECT> 

     <VALUE.OBJECT> 
     <INSTANCE CLASSNAME="Ecm_ProcessClass"> 
      <PROPERTY.REFERENCE NAME="Parent"> 
      <VALUE.REFERENCE> 
       <INSTANCENAME CLASSNAME="Ecm"> 
       <KEYBINDING NAME="Name"> 
        <KEYVALUE>ECM</KEYVALUE> 
       </KEYBINDING> 
       </INSTANCENAME> 
      </VALUE.REFERENCE> 
      </PROPERTY.REFERENCE> 
      <PROPERTY.REFERENCE NAME="Child"> 
      <VALUE.REFERENCE> 
       <INSTANCENAME CLASSNAME="ProcessClass"> 
       <KEYBINDING NAME="ClassID"> 
        <KEYVALUE>3</KEYVALUE> 
       </KEYBINDING> 
       </INSTANCENAME> 
      </VALUE.REFERENCE> 
      </PROPERTY.REFERENCE> 
     </INSTANCE> 
     </VALUE.OBJECT> 

     <VALUE.OBJECT> 
     <INSTANCE CLASSNAME="Ecm_ProcessClass"> 
      <PROPERTY.REFERENCE NAME="Parent"> 
      <VALUE.REFERENCE> 
       <INSTANCENAME CLASSNAME="Ecm"> 
       <KEYBINDING NAME="Name"> 
        <KEYVALUE>ECM</KEYVALUE> 
       </KEYBINDING> 
       </INSTANCENAME> 
      </VALUE.REFERENCE> 
      </PROPERTY.REFERENCE> 
      <PROPERTY.REFERENCE NAME="Child"> 
      <VALUE.REFERENCE> 
       <INSTANCENAME CLASSNAME="ProcessClass"> 
       <KEYBINDING NAME="ClassID"> 
        <KEYVALUE>1</KEYVALUE> 
       </KEYBINDING> 
       </INSTANCENAME> 
      </VALUE.REFERENCE> 
      </PROPERTY.REFERENCE> 
     </INSTANCE> 
     </VALUE.OBJECT> 

     <VALUE.OBJECT> 
     <INSTANCE CLASSNAME="Ecm_ProcessClass"> 
      <PROPERTY.REFERENCE NAME="Parent"> 
      <VALUE.REFERENCE> 
       <INSTANCENAME CLASSNAME="Ecm"> 
       <KEYBINDING NAME="Name"> 
        <KEYVALUE>ECM</KEYVALUE> 
       </KEYBINDING> 
       </INSTANCENAME> 
      </VALUE.REFERENCE> 
      </PROPERTY.REFERENCE> 
      <PROPERTY.REFERENCE NAME="Child"> 
      <VALUE.REFERENCE> 
       <INSTANCENAME CLASSNAME="ProcessClass"> 
       <KEYBINDING NAME="ClassID"> 
        <KEYVALUE>15</KEYVALUE> 
       </KEYBINDING> 
       </INSTANCENAME> 
      </VALUE.REFERENCE> 
      </PROPERTY.REFERENCE> 
     </INSTANCE> 
     </VALUE.OBJECT> 
     <VALUE.OBJECT> 
     <INSTANCE CLASSNAME="SharedGtTranslator"> 
      <QUALIFIER NAME="Configstate" TYPE="string"> 
      <VALUE>planned</VALUE> 
      </QUALIFIER> 
      <PROPERTY NAME="Name" TYPE="string"> 
      <VALUE>HLR$4,0,1,3,7240*-->HLR HLR LocalSPC: 410 SSN: 6</VALUE> 
      </PROPERTY> 
      <PROPERTY NAME="NatureOfAddress" TYPE="sint32"> 
      <VALUE>3</VALUE> 
      </PROPERTY> 
      <PROPERTY NAME="NetworkID" TYPE="sint32"> 
      <VALUE>1</VALUE> 
      </PROPERTY> 
      <PROPERTY NAME="NumberSeries" TYPE="sint32"> 
      <VALUE>7240*</VALUE> 
      </PROPERTY> 
      <PROPERTY NAME="NumberingPlan" TYPE="sint32"> 
      <VALUE>1</VALUE> 
      </PROPERTY> 
      <PROPERTY NAME="TranslationType" TYPE="sint32"> 
      <VALUE>0</VALUE> 
      </PROPERTY> 
     </INSTANCE> 
     </VALUE.OBJECT> 
     <VALUE.OBJECT> 
     <INSTANCE CLASSNAME="SharedGtTranslator"> 
      <QUALIFIER NAME="Configstate" TYPE="string"> 
      <VALUE>planned</VALUE> 
      </QUALIFIER> 
      <PROPERTY NAME="Name" TYPE="string"> 
      <VALUE>HLR$4,0,1,3,7250*-->HLR HLR LocalSPC: 410 SSN: 6</VALUE> 
      </PROPERTY> 
      <PROPERTY NAME="NatureOfAddress" TYPE="sint32"> 
      <VALUE>3</VALUE> 
      </PROPERTY> 
      <PROPERTY NAME="NetworkID" TYPE="sint32"> 
      <VALUE>1</VALUE> 
      </PROPERTY> 
      <PROPERTY NAME="NumberSeries" TYPE="sint32"> 
      <VALUE>7250*</VALUE> 
      </PROPERTY> 
      <PROPERTY NAME="NumberingPlan" TYPE="sint32"> 
      <VALUE>1</VALUE> 
      </PROPERTY> 
      <PROPERTY NAME="TranslationType" TYPE="sint32"> 
      <VALUE>0</VALUE> 
      </PROPERTY> 
     </INSTANCE> 
     </VALUE.OBJECT> 
    </DECLGROUP> 

    </DECLARATION> 
</CIM> 

新的文件將只包含這樣的:

<CIM> 
    <DECLARATION> 
    <DECLGROUP> 
      <VALUE.OBJECT> 
      <INSTANCE CLASSNAME="SharedGtTranslator"> 
       <QUALIFIER NAME="Configstate" TYPE="string"> 
       <VALUE>planned</VALUE> 
       </QUALIFIER> 
       <PROPERTY NAME="Name" TYPE="string"> 
       <VALUE>HLR$4,0,1,3,7240*-->HLR HLR LocalSPC: 410 SSN: 6</VALUE> 
       </PROPERTY> 
       <PROPERTY NAME="NatureOfAddress" TYPE="sint32"> 
       <VALUE>3</VALUE> 
       </PROPERTY> 
       <PROPERTY NAME="NetworkID" TYPE="sint32"> 
       <VALUE>1</VALUE> 
       </PROPERTY> 
       <PROPERTY NAME="NumberSeries" TYPE="sint32"> 
       <VALUE>7240*</VALUE> 
       </PROPERTY> 
       <PROPERTY NAME="NumberingPlan" TYPE="sint32"> 
       <VALUE>1</VALUE> 
       </PROPERTY> 
       <PROPERTY NAME="TranslationType" TYPE="sint32"> 
       <VALUE>0</VALUE> 
       </PROPERTY> 
      </INSTANCE> 
      </VALUE.OBJECT> 
      <VALUE.OBJECT> 
      <INSTANCE CLASSNAME="SharedGtTranslator"> 
       <QUALIFIER NAME="Configstate" TYPE="string"> 
       <VALUE>planned</VALUE> 
       </QUALIFIER> 
       <PROPERTY NAME="Name" TYPE="string"> 
       <VALUE>HLR$4,0,1,3,7250*-->HLR HLR LocalSPC: 410 SSN: 6</VALUE> 
       </PROPERTY> 
       <PROPERTY NAME="NatureOfAddress" TYPE="sint32"> 
       <VALUE>3</VALUE> 
       </PROPERTY> 
       <PROPERTY NAME="NetworkID" TYPE="sint32"> 
       <VALUE>1</VALUE> 
       </PROPERTY> 
       <PROPERTY NAME="NumberSeries" TYPE="sint32"> 
       <VALUE>7250*</VALUE> 
       </PROPERTY> 
       <PROPERTY NAME="NumberingPlan" TYPE="sint32"> 
       <VALUE>1</VALUE> 
       </PROPERTY> 
       <PROPERTY NAME="TranslationType" TYPE="sint32"> 
       <VALUE>0</VALUE> 
       </PROPERTY> 
      </INSTANCE> 
      </VALUE.OBJECT> 
    </DECLGROUP> 

    </DECLARATION> 
</CIM> 
+0

似乎我找到了我的答案[here](http://stackoverflow.com/questions/7222637/xmllibxmls-notion-of-a-text-nodes-parent) – vobelic 2013-04-24 12:56:36

回答

1

如果需要VALUE.OBJECT結構那麼我建議你先找到這些,和然後在裏面尋找給你名字的PROPERTY元素。

這段代碼實現了這個想法。它查找所有具有INSTANCE子項的數據中的所有VALUE.OBJECT元素,其CLASSNAME屬性等於SharedGtTranslator。對於這些元素,使用toString來顯示整個元素的XML,並通過查找具有NAME屬性等於NameINSTANCE子項和PROPERTY子項來查找並顯示名稱。

我也改變了從文件中解析數據的方式,因爲你說你被卡住的XML::LibXML版本沒有load_xml方法。

請注意,findnodes方法將始終返回節點列表,如果調用在列表上下文中,則作爲Perl列表返回;如果該列表處於scdalar上下文中,則作爲XML::LibXML::NodeList對象返回。無論XPath表達式是否有多個,一個或零個匹配項,都是如此,並且如果您有任何疑問,應該在處理繼續之前檢查找到的節點數。

use strict; 
use warnings; 

use XML::LibXML; 

my $doc = XML::LibXML->new(no_blanks => 1)->parse_file($file1); 

my @value_objects = $doc->findnodes('//VALUE.OBJECT[INSTANCE[@CLASSNAME = "SharedGtTranslator"]]'); 

for my $value_object (@value_objects) { 

    print "\n"; 
    print $value_object->toString(1), "\n"; 
    print "\n"; 

    my @names = $value_object->findnodes('INSTANCE/PROPERTY[@NAME = "Name"]'); 
    print $names[0]->textContent, "\n"; 
}