Как я могу распечатать XPath из l xml элементов дерева? - PullRequest
0 голосов
/ 13 февраля 2020

Я пытаюсь напечатать XPath всех элементов в дереве XML, но при использовании l xml получаю странный вывод. Вместо xpath, который содержит имя каждого узла в пути, я получаю странный вывод "*". Вы знаете, в чем может быть проблема здесь? Здесь код, а также XML, который я пытаюсь проанализировать.

from lxml import etree

xml = """
<filter xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <bundles xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-bundlemgr-oper">
    <bundles>
      <bundle>
        <data>
            <bundle-status/>
            <lacp-status/>
            <minimum-active-links/>
            <ipv4bfd-status/>
            <active-member-count/>
            <active-member-configured/>
        </data>
        <members>
            <member>
                <member-interface/>
                <interface-name/>
                <member-mux-data>
                    <member-state/>
                </member-mux-data>
            </member>
        </members>
        <bundle-interface>{{bundle_name}}</bundle-interface>
      </bundle>
    </bundles>
  </bundles>
  <bfd xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-ip-bfd-oper">
    <session-briefs>
        <session-brief>
            <state/>
            <interface-name>{{bundle_name}}</interface-name>
        </session-brief>
    </session-briefs>
  </bfd>
</filter>
"""


root = etree.XML(xml)
tree = etree.ElementTree(root)
for element in root.iter():
    print(tree.getpath(element))

Вывод выглядит следующим образом (вместо "*" должны быть имена узлов):

/*
/*/*[1]
/*/*[1]/*
/*/*[1]/*/*
/*/*[1]/*/*/*[1]
/*/*[1]/*/*/*[1]/*[1]
/*/*[1]/*/*/*[1]/*[2]
/*/*[1]/*/*/*[1]/*[3]
/*/*[1]/*/*/*[1]/*[4]
/*/*[1]/*/*/*[1]/*[5]
/*/*[1]/*/*/*[1]/*[6]
/*/*[1]/*/*/*[2]
/*/*[1]/*/*/*[2]/*
/*/*[1]/*/*/*[2]/*/*[1]
/*/*[1]/*/*/*[2]/*/*[2]
/*/*[1]/*/*/*[2]/*/*[3]
/*/*[1]/*/*/*[2]/*/*[3]/*
/*/*[1]/*/*/*[3]
/*/*[2]
/*/*[2]/*
/*/*[2]/*/*
/*/*[2]/*/*/*[1]
/*/*[2]/*/*/*[2]

Большое спасибо! Драган

1 Ответ

0 голосов
/ 22 февраля 2020

Я обнаружил, что, кроме getpath , etree содержит также "родственный" метод с именем getelementpath , который дает надлежащий результат также для элементов пространства имен.

Поэтому измените свой код на:

for element in root.iter():
    print(tree.getelementpath(element))

Для исходного примера с сокращенными для удобства чтения пространствами имен начальная часть результата выглядит следующим образом:

.
{http://cisco.com/ns}bundles
{http://cisco.com/ns}bundles/{http://cisco.com/ns}bundles
...