python xpath返回空列表

问题描述:

我已经通过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。

任何帮助表示赞赏。

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"]]')) 

尝试使用命名空间前缀:

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