2017-02-04 149 views
2

我已經通過xpath & lxml讀了大量的線程,但我仍然認爲對於下面的xml缺少一些東西。python xpath返回空列表

我需要將'rt-entry'項目及其下的信息一起拉出來。

我想在python以下幾點:

from lxml import etree 

x=""" 
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/12.3R5/junos"> 
    <route-information xmlns="http://xml.juniper.net/junos/12.3R5/junos-routing"> 
     <route-table> 
      <table-name>x.inet.0</table-name> 
      <destination-count>4990</destination-count> 
      <total-route-count>51326</total-route-count> 
      <active-route-count>4990</active-route-count> 
      <holddown-route-count>0</holddown-route-count> 
      <hidden-route-count>0</hidden-route-count> 
      <rt junos:style="detail"> 
       <rt-destination>x.x.x.x</rt-destination> 
       <rt-prefix-length>14</rt-prefix-length> 
       <rt-entry-count junos:format="2 entries">2</rt-entry-count> 
       <rt-announced-count>1</rt-announced-count> 
       <tsi junos:indent="0"> 
        KRT in-kernel x.x.x.x/x -> {indirect(x)} 
        Page 0 idx 0 Type 1 val b4557d8 
         Flags: Nexthop Change 
         Nexthop: Self 
         Localpref: 100 
         AS path: [x] I 
        Path x.x.x.x from x.x.x.x Vector len 4. Val: 0 
       </tsi> 
       <rt-entry> 
        <active-tag>*</active-tag> 
        <current-active/> 
        <last-active/> 
        <protocol-name>BGP</protocol-name> 
        <preference>170</preference> 
        <preference2>-101</preference2> 
        <nh-type>Indirect</nh-type> 
        <nh-address>x</nh-address> 
        <nh-reference-count>123</nh-reference-count> 
        <nh-kernel-id>0</nh-kernel-id> 
        <gateway>x.x.x.x</gateway> 
        <nh-type>Router</nh-type> 
        <nh-index>1538</nh-index> 
        <nh junos:indent="16"> 
         <nh-string>Next hop</nh-string> 
         <to>x.x.x.x</to> 
         <via>x.x</via> 
         <selected-next-hop/> 
         <session>63</session> 
        </nh> 
        <protocol-nh junos:indent="16"> 
         <to>x.x.x.x</to> 
         <indirect-nh>bac2c40 1048576 INH Session ID: 0xa7</indirect-nh> 
        </protocol-nh> 
        <rt-entry-state>Active Int Ext</rt-entry-state> 
        <peer-as>x</peer-as> 
        <announce-bits>3</announce-bits> 
        <announce-tasks>0-KRT 2-BGP_RT_Background 3-Resolve tree 7 </announce-tasks> 
        <as-path>AS path: I 
        </as-path> 
        <bgp-rt-flag>Accepted</bgp-rt-flag> 
        <local-preference>100</local-preference> 
        <peer-id>x.x.x.x</peer-id> 
        <indirect-nh-count>1</indirect-nh-count> 
        <protocol-nh junos:indent="24"> 
         <to>x.x.x.x</to> 
         <indirect-nh>bac2c40 1048576 INH Session ID: 0xa7</indirect-nh> 
         <forwarding-nh-count>1</forwarding-nh-count> 
         <nh-type>Router</nh-type> 
         <nh-index>1538</nh-index> 
         <nh junos:indent="8"> 
          <nh-string>Next hop</nh-string> 
          <to>x.x.x.x</to> 
          <via>x.x</via> 
          <session>63</session> 
         </nh> 
         <output> 
             x.x.x.x/x Originating RIB: x.inet.0 
              Node path count: 1 
              Forwarding nexthops: 1 
              Next hop type: Interface 
              Nexthop: via x.x 
         </output> 
        </protocol-nh> 
       </rt-entry> 
      </rt> 
     </route-table> 
    </route-information> 
    <cli> 
     <banner>{master}</banner> 
    </cli> 
</rpc-reply> 
""" 

root=etree.fromstring(x) 
print(root.xpath('//rt-entry[current-active]')) 

不過,我收到一個空列表。我的xpath是錯誤的,或者我錯誤地使用了lxml。

任何幫助表示讚賞。

回答

2

xmlns:junos="http://xml.juniper.net/junos/12.3R5/junos"聲明位於rpc-reply根元素上,您的XML源將整個文檔放入命名空間。

所以,你要麼需要使用一個命名空間的XPath表達式,或者只是使用local-name()

print(root.xpath('//*[local-name() = "rt-entry"][*[local-name() = "current-active"]]')) 
4

嘗試使用命名空間前綴:

print (root.xpath('//junos-routing:rt-entry',namespaces={"junos-routing":"http://xml.juniper.net/junos/12.3R5/junos-routing"})) 

裁判: http://lxml.de/xpathxslt.html

+0

Upvoted,在dict中聲明這個命名空間比使用'local-name()'忽略它更好。 –

+0

感謝您的幫助,這爲我解決了它。有沒有簡單的方法來通過lxml捕獲命名空間?現在我只是將根條目轉換爲一個字符串並將其拆分。 – Dayde

+0

@Dayde我沒有更好的解決方案,循環兒童元素來獲取名稱空間? (): print elem.nsmap' – TopCaver