2012-03-29 15 views
1

我目前有一個Perl CGI腳本,它使用XML::Simple解析傳入的XML請求。進入XML的約定如下:訪問XML中的動態嵌套值對

<?xml version="1.0" encoding="utf-8" ?> 
<XMLRequest> 
    <CORE> 
    <CORE ID="14"> 
     <PARENT_ID>1</PARENT_ID> 
     <CORE_ID>14</CORE_ID> 
     <FORM_ID>1423</FORM_ID> 
     <SECURITY_ID>1</SECURITY_ID> 
     <AREA_ID>3</AREA_ID> 
     <SUB_PARENT_ID>1</SUB_PARENT_ID> 
     <SUB_AREA_ID>1</SUB_AREA_ID> 
    </CORE> 
    <CORE ID="15"> 
     <PARENT_ID>1</PARENT_ID> 
     <CORE_ID>15</CORE_ID> 
     <FORM_ID>1424</FORM_ID> 
     <SECURITY_ID>1</SECURITY_ID> 
     <AREA_ID>3</AREA_ID> 
     <SUB_PARENT_ID>1</SUB_PARENT_ID> 
     <SUB_AREA_ID>2</SUB_AREA_ID> 
    </CORE> 
    </CORE> 
</XMLRequest> 

我需要去的名稱/值對,並從約定,名字成分是「核心」,併爲「ID」的值的值。儘管如此,挑戰是'核心',在這個公約中代表了一個不斷變化的可能值列表。 AS是,XMLin解析該XML,以便最頂層和次要的'CORE'是散列,但是接着是'ID'和其餘數據作爲散列數組。

我已經從使用XML :: Simple的KeyAttr選項的方面着手,並列出了值爲'CORE'的所有可能的變體,但這是一個不斷變化的列表,因此這是不可行的。另一種是使用嵌套的Whiles和For語句來查看所需的組件,但這似乎違反直覺。我開始研究XML :: LibXML,但看起來更難以理解。

建議非常感謝。

+0

嗯,似乎一個XPath/XQuery的工作,看,如果你的lib支持XPath表達式,在這種情況下,核心節點與/ XMLRequest/CORE/CORE選擇(每個核心CORE節點的子節點,XmlRequest節點的子節點) – BigMike 2012-03-29 15:01:18

+0

請解釋您的XML如何更改。僅僅是''元素可以有不同的標籤名稱?外部''元素是否總是與內部元素具有相同的名稱?你是否只想要每個具有「ID」屬性的元素? – Borodin 2012-03-29 15:34:45

回答

2

我發現XML::Simple比簡單的更加尷尬,並會強烈建議你進步到XML::LibXMLXML::Twig如果只是爲了獲得進入XPath表達式訪問XML DOM。

這裏有一些代碼可以用你的XML來做我想用的東西。它會查找具有ID屬性的根元素<XMLRequest>下兩個級別的所有元素,並報告該元素的標記名稱及其ID屬性值。正如你所看到的,它只用了幾行就完成了。

use strict; 
use warnings; 

use XML::LibXML; 

my $xml = XML::LibXML->load_xml(string => <<XML); 
<?xml version="1.0" encoding="utf-8" ?> 
<XMLRequest> 
    <CORE> 
    <CORE ID="14"> 
     <PARENT_ID>1</PARENT_ID> 
     <CORE_ID>14</CORE_ID> 
     <FORM_ID>1423</FORM_ID> 
     <SECURITY_ID>1</SECURITY_ID> 
     <AREA_ID>3</AREA_ID> 
     <SUB_PARENT_ID>1</SUB_PARENT_ID> 
     <SUB_AREA_ID>1</SUB_AREA_ID> 
    </CORE> 
    <CORE ID="15"> 
     <PARENT_ID>1</PARENT_ID> 
     <CORE_ID>15</CORE_ID> 
     <FORM_ID>1424</FORM_ID> 
     <SECURITY_ID>1</SECURITY_ID> 
     <AREA_ID>3</AREA_ID> 
     <SUB_PARENT_ID>1</SUB_PARENT_ID> 
     <SUB_AREA_ID>2</SUB_AREA_ID> 
    </CORE> 
    </CORE> 
</XMLRequest> 
XML 

foreach my $node ($xml->findnodes('/XMLRequest/*/*[@ID]')) { 
    printf "%s => %d\n", $node->nodeName, $node->getAttribute('ID'); 
} 

輸出

CORE => 14 
CORE => 15 
+0

謝謝!這確實有訣竅! – Namuna 2012-03-30 15:38:34