我有一个程序,它比较来自不同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_text
和set_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>
通知书?
答案 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_xpath
和root
都会返回“元素”对象。 (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_text
和set_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',因为这应该是无关紧要的)。