使用其他XML文件中的值覆盖XML文件中的某些值

时间:2017-03-15 17:04:09

标签: xml perl xml-parsing

我有一个程序,它比较来自不同XML文档(ipAddress和设备名称)的某些值。

  use strict;
  use warnings;
  use XML::Twig;

  my $xml1 = XML::Twig->new->parsefile('FILE1.xml');
  my $xml2 = XML::Twig->new->parsefile('FILE2.xml');

  if ( ( $xml1->get_xpath( '//deviceName', 0 )->text eq $xml2->root->att('name') )
  && ( $xml1->get_xpath( '//ipAddress', 0 )->text eq $xml2->get_xpath( '//ipaddress', 0 )->text ) )

  {
   print "IP and name  matches\n";
     } else {
        ...

如果两者都相同,我只想要看到这条消息,但如果两者不同,我想用FILE2制作一个POST请求但是使用FILE1的值。 现在我想在我的FILE2中保存这个值(ipAddress和name)。我应该覆盖它们并保存。

我用什么方法来制作它?

我尝试保存我的值并使用set_textset_att覆盖它们(因为我在FILE2 name作为属性)但我不确定我应该这样做......

    .......
    } else {
my $name1 = $xml1->get_xpath( '//deviceName', 0 )->text;
my $Addr1 = $xml1->get_xpath( '//ipAddress', 0 )->text;
my $name2 = $xml2->root->att('name');
my $Addr2 = $xml2->get_xpath( '//ipaddress', 0 )->text;

XML::Twig->new(
pretty_print  => 'indented',
twig_handlers => {
    name => sub {
        $name2->set_text( $name1)->flush  && $Addr2->set_att($Addr2)->flush
    },
   },
 )->parsefile_inplace( 'FILE2.xml');

 }

FILE1.xml

  <?xml version="1.0" ?>
  <queryResponse last="34" first="0" count="35" type="Devices" responseType="listEntityInstances" requestUrl="https://hostname/webacs/api/v1/data/Devices?.full=true" rootUrl="https://hostname/webacs/api/v1/da$
   <entity dtoType="devicesDTO" type="Devices" url="https://hostname/webacs/api/v1/data/Devices/201">
  <devicesDTO displayName="201201" id="201">
    <clearedAlarms>0</clearedAlarms>
    <collectionDetail></collectionDetail>
    <collectionTime></collectionTime>
    <creationTime></creationTime>
    <criticalAlarms>0</criticalAlarms>
    <deviceId>205571</deviceId>
    <deviceName>TEST</deviceName>
    <deviceType>Cisco Switch</deviceType>
    <informationAlarms>0</informationAlarms>
    <ipAddress>10.66.12.126</ipAddress>
  <location></location>
    <majorAlarms>0</majorAlarms>
    <managementStatus></managementStatus>
       <manufacturerPartNrs>
           <manufacturerPartNr></manufacturerPartNr>
       </manufacturerPartNrs>
       <minorAlarms>0</minorAlarms>
       <productFamily></productFamily>
       <reachability>Reachable</reachability>
       <softwareType></softwareType>
       <softwareVersion></softwareVersion>
       <warningAlarms>0</warningAlarms>
  </devicesDTO>

FILE2.xml

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<ns3:networkdevice name="Hallo" id="9999999981be-b83861d71f95" xmlns:ns2="ers.ise.cisco.com" xmlns:ns3="network.ers.ise.cisco.com">
<link type="application/xml" href="https://hostname:9060/ers/config/networkdevice/123456" rel="self"/>
 <authenticationSettings>
    <enableKeyWrap>false</enableKeyWrap>
    <keyInputFormat>ASCII</keyInputFormat>
    <networkProtocol>RADIUS</networkProtocol>
    <radiusSharedSecret>******</radiusSharedSecret>
 </authenticationSettings>
 <NetworkDeviceIPList>
   <NetworkDeviceIP>
      <ipaddress>10.66.12.127</ipaddress>
      <mask>21</mask>
   </NetworkDeviceIP>
 </NetworkDeviceIPList>
 <NetworkDeviceGroupList>
   <NetworkDeviceGroup>Location#All Locations</NetworkDeviceGroup>
   <NetworkDeviceGroup>Device Type#All Device Types</NetworkDeviceGroup>
  </NetworkDeviceGroupList>
  </ns3:networkdevice>

通知书?

1 个答案:

答案 0 :(得分:1)

参考您的previous question

您需要阅读XML::Twig文档中的set_att内容。

你这样做:

$xml2->root->set_att('name', 
                      $xml1->get_xpath( '//deviceName', 0 )->text );

$xml2->get_xpath('//ipaddress',0) -> set_text (
               $xml1->get_xpath( '//ipAddress', 0 )->text );

$xml2 -> set_pretty_print ('indented_a');
$xml2 -> print;

为了清楚起见,get_xpathroot都会返回“元素”对象。 (get_xpath('//element',0)只返回一个,你可以操作。但get_xpath('//element')返回一个匹配列表,你需要迭代它。

但是XML::Twig::Elt是一种数据结构,包括内容,属性,名称和父/子元素的链接。

您可以通过text()att('attributename')获取此元素。

所以,例如

<element name="bernard" animal="haddock">This is bernard the fish</element>

这个元素你会得到“这是伯纳德鱼”$element -> text$element->att('name')返回'伯纳德'。 ($element -> tag将返回'element'

您可以使用set_textset_att对此进行操作。如果存在则覆盖两者,如果不存在则覆盖。这就是它的全部

$element -> set_att('location','fish tank'); 

将上述内容变为:

<element name="bernard" animal="haddock" location="fish tank">This is bernard the fish</element>

(注意 - 属性不一定是有序的,这是为什么正则表达式hackery是一个问题的一部分)

实际上,您可能希望将POST设置为$xml2->sprint(有或没有'set_pretty_print',因为这应该是无关紧要的)。