2017-03-17 85 views
0

我有兩個XML文件。在第一個我有一些設備已經在數據庫(標籤ipAddress是重要的)。 第二個XML文件包含那些應該添加的設備/設備,如果它們不在數據庫(發佈請求)。要比較xml文件中具有相同名稱的標籤與其他xml文件中的其他標籤

我已經有了比較兩個XML文件的代碼,如果他們只有一個設備(一個標籤與ipAddress)。

FILE1(包含30個設備,例如我只添加了2個)。

<?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/data"> 
    <entity dtoType="devicesDTO" type="Devices" url="https://hostname/webacs/api/v1/data/Devices/200"> 
    <devicesDTO displayName="201200" id="200"> 
     <deviceName>NEW</deviceName> 
     <deviceType>Cisco Switch</deviceType> 
     <ipAddress>10.66.12.128</ipAddress> 
    </devicesDTO> 
    </entity> 
    <entity dtoType="devicesDTO" type="Devices" url="https://hostname/webacs/api/v1/data/Devices/201"> 
    <devicesDTO displayName="201201" id="201"> 
     <deviceName>NEW-SWW</deviceName> 
     <deviceType>Cisco Switch</deviceType> 
     <ipAddress>10.66.12.127</ipAddress> 
    </devicesDTO> 
    </entity> 
</queryResponse> 

FILE2(可以是一個或多個設備)

<?xml version="1.0"?> 
    <devicesImport> 
    <devices> 
     <device> 
     <ipAddress>10.66.0.8</ipAddress> 
     <networkMask>24</networkMask> 
     <snmpWriteCommunity>labor</snmpWriteCommunity> 
     <udfs> 
     <udf> 
      <name>LaborTest</name> 
     </udf> 
     </udfs> 
    </device> 
    </devices> 
    </devicesImport> 
    <devicesImport> 
    <devices> 
     <device> 
     <ipAddress>10.66.0.9</ipAddress> 
     <networkMask>24</networkMask> 
     <snmpWriteCommunity>labor</snmpWriteCommunity> 
     <udfs> 
     <udf> 
      <name>LaborTest</name> 
     </udf> 
     </udfs> 
    </devices> 
    </devices> 
</devicesImport> 

我的代碼:

#!/usr/bin/env perl 
use strict; 
use warnings; 
use XML::Twig; 


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

#$xml2->findnodes('./ipAddress/*'); # I tried to cover all ipAddress from FILE1 

    #Next Try to do it other way 
    #foreach $xml1->get_xpath('//ipAddress', 0)->text { 
    #foreach $xml2->get_xpath('//ipAddress', 0)->text { 


    # I compare here just one tag from both files (it works if my file contains just one device) 
    if ($xml1->get_xpath('//ipAddress', 0)->text 
    eq $xml2->get_xpath('//ipAddress', 0)->text) 

    { 
    print "IP matches\n"; 
    } 

我也試過

if (($xml1->get_xpath('//ipAddress', 0)->text 
    eq $xml2->get_xpath('//ipAddress', 0)->text) 
    for $xml2->findnodes ('//ipAddress')); 

,但它不工作。

+0

不要在你的列表中的那些條目實際上相關?他們沒有相同的名字或IP? – Sobrique

+0

另外 - 第一個'文件'似乎是兩個單獨的XML文檔。這是故意的嗎? – Sobrique

+0

不,它不應該是兩個單獨的XML文檔,是一個錯誤 – StayCalm

回答

2

好的,所以這裏的東西是get_xpath定位符合特定標準的節點。

如果您確定按照相同的順序收到東西,您可以獲得兩個get_xpath響應列表並對它們進行迭代。

但我不認爲這是一個安全的假設,在XML - 一個設備可能會丟失。

因此,您需要編寫一個search - get_xpath也可以這樣做。

您的輸入存在一些問題,雖然 - FILE1.xml您已經到了,實際上是兩個單獨的XML文檔。兩者之間沒有root標記,並且有兩次<?xml聲明。

因此,您需要稍微轉換它以使其成爲單個文檔(或單獨解析)。與FILE2.xml一樣 - 最後有兩個</devices>標籤(其中一個應該是</device>)。請你用有效的XML,因爲各種東西,如果你不打破:

但是爲了說明,我假設他們是一個單一的文件:

#!/usr/bin/env perl 
use strict; 
use warnings; 
use XML::Twig; 

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

foreach my $device ($xml2->get_xpath('//device')) { 
    my $ip_addr = $device->first_child_text('ipAddress'); 
    print "Looking for $ip_addr\n"; 
    if (my $search = $xml1->get_xpath("//ipAddress[string()=\"$ip_addr\"]")) 
    { 
     print "Found: ", $search->parent->first_child_text('deviceName'), "\n"; 
    } 
    else { 
     print "Didn't find match for: ", 
     $device->get_xpath('.//name', 0)->text, "\n"; 
    } 
} 

現在,有在這裏沒有找到,因爲你的IP在你的兩個文件中不匹配。

XML::Twig有什麼可以與xpath所以它的價值檢查做的侷限性quick reference guide(這是XML :: LibXML`進入它自己 - 它的功能更全面)

相關問題