使用Perl/LibXML获取其子元素匹配标准的XML父元素



我使用的是XML::LibXML(仅限于v1.58)。感谢Borodin在这篇文章中,我正确地获得了PROPERTY NAME="Name"如果CLASSNAME="SharedGtTranslator"的值。我还想获得包含上述内容的整个VALUE.OBJECT父元素,并将其输出到另一个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>

如果您需要VALUE.OBJECT结构,那么我建议您先找到这些结构,然后在其中查找给您名称的PROPERTY元素。

这段代码表达了这个想法。它查找数据中所有具有INSTANCE子元素且CLASSNAME属性等于SharedGtTranslatorVALUE.OBJECT元素。对于这些元素,使用toString显示整个元素的XML,通过查找INSTANCE子元素,然后查找具有NAME属性等于NamePROPERTY子元素来查找和显示名称。

我也改变了数据从文件中解析的方式,因为你说你被卡住了一个没有load_xml方法的XML::LibXML版本。

注意,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";
}

相关内容

  • 没有找到相关文章

最新更新