1

I have a Programm that compares certain values from different XML Documents (ipAddress and Device Name).

  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 {
        ...

If both are the same I just want want to see this message, but if both are different I want to make a POST Request with FILE2 but with the values from FILE1. Now I want to save this values (ipAddress and name) in my FILE2. I should to overwrite them and save.

What methods schould I use to make that?

I tried to save my values and to overrwite them with with set_text and set_att(because I have in FILE2 name as attribute) but I'm not sure that I should do it this way...

    .......
    } 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>

Advices?

StayCalm
  • 145
  • 2
  • 13
  • Perhaps [this answer](http://stackoverflow.com/a/41484175/4653379) can be useful, for manipulating elements in `XML::Twig`. Also, [this answer](http://stackoverflow.com/a/38069658/4653379) builds an XML file with `XML::Twig`. – zdim Mar 15 '17 at 18:20
  • I thought you were comparing them? – simbabque Mar 15 '17 at 20:47
  • It was the first step...I should compare them to see, whether should I make Post request or not...if my values are different I take values from DB1 and post them to DB2. – StayCalm Mar 16 '17 at 07:59

1 Answers1

1

With reference to your previous question:

You need to go read what set_att does in the XML::Twig documentation.

You do it like this:

$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;

For the sake of clarity - both get_xpath and root return an 'element' object. (get_xpath('//element',0) returns just a single one, which you can manipulate. However get_xpath('//element') returns a list of matches, and you'd need to iterate it.

But an XML::Twig::Elt is a data structure that includes content, attributes, names and links to parent/child elements.

This element you get values out of via text() and att('attributename').

So e.g.

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

This element you'd be getting "This is bernard the fish" with $element -> text and $element->att('name') returns 'bernard'. (and $element -> tag will return 'element'

And you can manipulate this with set_text and set_att. Both overwrite if any is existing, and adds if not. And that's all there is to it

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

Would turn the above into:

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

(Note though - attributes aren't necessarily ordered, which is part of why regex hackery is a problem)

Actually, you probably want to set your POST to $xml2->sprint (with or without 'set_pretty_print' as that should be irrelevant).

Community
  • 1
  • 1
Sobrique
  • 52,974
  • 7
  • 60
  • 101
  • Thank you! I have tried to do that by my own..but I'm new in Perl and it is not so easy to understand to to use some methods... I used `$xml2->sprint` and my POST works. – StayCalm Mar 16 '17 at 12:15
  • You've a treat ahead of you. Perl is a really marvellous language to work with. – Sobrique Mar 16 '17 at 13:34