2

I've read through a ton of threads on xpath & lxml, but I still seem to missing something with regards to the following xml.

I need to pull the 'rt-entry' item, along with the information under it.

I am trying the following in 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]'))

However, I receive an empty list. Either my xpath is wrong, or I am using lxml incorrectly.

Any help is appreciated.

Dayde
  • 21
  • 2
  • The `xmlns:junos="http://xml.juniper.net/junos/12.3R5/junos"` declaration that’s on the `rpc-reply` root element your XML source puts the entire document into a namespace. So you either need to use a namespace-aware XPath expression, or else just use `local-name()`; like this: `print(root.xpath('//*[local-name() = "rt-entry"][*[local-name() = "current-active"]]'))` – sideshowbarker May 16 '19 at 01:02

1 Answers1

4

Try to use namespace prefixes:

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

ref: http://lxml.de/xpathxslt.html

TopCaver
  • 369
  • 4
  • 9
  • Upvoted, declaring this namespace in a dict is better than ignoring it with `local-name()`. – Mathias Müller Feb 04 '17 at 09:41
  • Thanks for the help, this solved it for me. Is there an easy way to capture the namespace via lxml? For now I am just turning the root entry into a string and splitting it. – Dayde Feb 05 '17 at 04:52
  • @Dayde I've no better solution, loop children elements to get namespaces? `for elem in root.getchildren(): print elem.nsmap` – TopCaver Feb 05 '17 at 06:52
  • That works for me.. better than me splitting the string to parse out the namespace. – Dayde Feb 05 '17 at 17:46