有没有办法使用中断的 XML 树结构检索树结构?

Is there a way to retrieve tree structure with break XML tree structure?

提问人:Michal 提问时间:4/18/2023 最后编辑:Michal 更新时间:4/18/2023 访问量:67

问:

我正在尝试遍历具有许多嵌套子项的XML文件。据我了解,常见的XML结构具有父>子项>许多其他子项等...

当这种结构不是那么严格并且它被用作某种节点HEAD_NODE和节点编号的链表时会发生什么。其中,祖先HEAD_NODE指向父级的 NODE,从而创建整个结构。

...            
           <AAA>
              <BB>
                <HEAD_NODE>         0</HEAD_NODE>
                <NODE>         1</NODE>
                <LVL>         1</LVL>
                ...
                <BB>
                  <HEAD_NODE>         1</HEAD_NODE>
                  <NODE>         2</NODE>
                  <LVL>         2</LVL>
                  ...
                  <BB>
                    <HEAD_NODE>         2</HEAD_NODE>
                    <NODE>         3</NODE>
            <LVL>         3</LVL>
                    ...
                   
                    <BB>
                      <HEAD_NODE>         3</HEAD_NODE>
                      <NODE>         4</NODE>
                      <LVL>         4</LVL>
                      ...
                      <BB>
                        <HEAD_NODE>         4</HEAD_NODE>
                        <NODE>         5</NODE>
                        <LVL>         5</LVL>
                        ...
            
                      <BB>
                      <HEAD_NODE>         3</HEAD_NODE>
                      <NODE>        17</NODE>
                      <LVL>         4</LVL>
                      ...
                      <BB>
                        <HEAD_NODE>        17</HEAD_NODE>
                        <NODE>        18</NODE>
                        <LVL>         5</LVL>
                        ...
                      </BB>
                      <BB>
                        <HEAD_NODE>        17</HEAD_NODE>
                        <NODE>        19</NODE>
                        <LVL>         5</LVL>
                        ...
                     <BB>
                      <HEAD_NODE>         3</HEAD_NODE>
                      <NODE>       145</NODE>
                      <LVL>         4</LVL>
                      
                      <BB>
                        <HEAD_NODE>       145</HEAD_NODE>
                        <NODE>       163</NODE>
                        <LVL>         5</LVL>
                        
                      </BB>
                      <BB>
                        <HEAD_NODE>       145</HEAD_NODE>
                        <NODE>       164</NODE>
                        <LVL>         5</LVL>
                        
                      </BB>
                      <BB>
                        <HEAD_NODE>       145</HEAD_NODE>
                        <NODE>       165</NODE>
                        <LVL>         5</LVL>
                        
                      </BB>
                      <BB>
                        <HEAD_NODE>       145</HEAD_NODE>
                        <NODE>       166</NODE>
                        <LVL>         5</LVL>
                        
                      </BB>
                      <BB>
                        <HEAD_NODE>       145</HEAD_NODE>
                        <NODE>       167</NODE>
                        <LVL>         5</LVL>
                        
                      </BB>
                      <BB>
                        <HEAD_NODE>       145</HEAD_NODE>
                        <NODE>       168</NODE>
                        <LVL>         5</LVL>
                        ...
                      </BB>
...

在某些情况下,此结构对应于 XML 结构,但在某些情况下则不对应。

使用 Xpath,我能够获得叶节点,基本上是应该在这些树末尾的节点。

from lxml import etree

tree = etree.parse('file.xml')
root = tree.getroot()

leaf_elements = root.xpath('//*[local-name()="BB"][not(.//*[local-name()="BB"])]/*[local-name()="HEAD_NODE"]')

我的问题是,如何以某种有意义的方式去收获所有这些树(所有这些节点都包含其他信息,我也希望看到这条路径)。

感谢您的任何提示。

更新

我混合了库,它返回了更好的结果。它仍然不是 100% 的解决方案,但已经接近了networkxlxml

from lxml import etree
import networkx as nx

# create empty graph
G = nx.DiGraph()

for head_node in root.xpath('//ns:HEAD_NODE', namespaces=ns):
    node_id = head_node.text.strip()
    
    G.add_node(head_node)
    
    for node in head_node.xpath('./following-sibling::ns:NODE', namespaces=ns):
        child_id = node.text.strip()
        G.add_edge(node_id, child_id)
    
# I can look for all these path
nx.shortest_path(G, source='0', target='442')```

python xml xpath xml 解析

评论

2赞 Michael Butscher 4/18/2023
如果它在节点之间有任意连接,则称为“图”。有许多算法和库可以遍历和操作图形。
0赞 Michal 4/18/2023
是的,我同意它是一种图形,但是xpath不应该也能够读取/加载它吗?因为当我使用朴素的解决方案(嵌套循环)时,时间消耗太大,而带有 lxml 的 xpath 要快得多。
0赞 Michael Butscher 4/18/2023
也许 XPath 专家有一些想法,但通常 XPath 是为 XML 结构而设计的。
1赞 Michael Butscher 4/18/2023
如果您不限于 XML,则 networkx.org
1赞 Conal Tuohy 4/18/2023
如果你了解 XPath 3.1,或者准备学习它,那么在 XPath 3.1 版本中,这种事情是相当容易的。您可以使用以下库: pypi.org/project/saxonche 在 Python 中启用 XPath 3.1。使用 lxml 时,您只能使用 XPath 1.0 版,该版本非常过时,并且不足以满足您的目的。使用 XPath 1.0 时,您需要在 Python 中编写图形遍历代码,并且仅将 XPath 用于查找。

答: 暂无答案