访问XML中的动态嵌套值对

时间:2012-03-29 14:55:53

标签: xml perl

我目前有一个Perl CGI脚本,使用XML::Simple解析传入的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>

我需要获取名称/值对,并且从约定中,名称组件是“CORE”,值是“ID”的值。然而,挑战是“CORE”,在此约定中代表了可能值的变化列表。 AS是,XMLin解析XML,以便最顶层和辅助'CORE'是哈希值,然后是'ID',其余数据是哈希数组。

我从使用XML :: Simple的KeyAttr选项并列出值的所有可能的“CORE”变体方面已经解决了这个问题,但这是一个不断变化的列表,因此这是不可行的。另一个是使用嵌套的Whiles和For语句来获取所需的组件,但这似乎是违反直觉的。我开始研究XML :: LibXML,但跳进去似乎有点令人生畏。

建议非常感谢。

1 个答案:

答案 0 :(得分:2)

我发现XML::Simple比简单更尴尬,如果只是为了访问XPath表达式来访问XML DOM,强烈建议你进展到XML::LibXMLXML::Twig

这是一些代码,用于执行我认为您想要的XML。它会在根<XMLRequest>元素下面的两个级别找到具有ID属性的所有元素,并报告该元素的标记名称及其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
相关问题