16

XML:

<?xml version="1.0"?>
<pages>
    <page>
        <url>http://example.com/Labs</url>
        <title>Labs</title>
        <subpages>
            <page>
                <url>http://example.com/Labs/Email</url>
                <title>Email</title>
                <subpages>
                    <page/>
                    <url>http://example.com/Labs/Email/How_to</url>
                    <title>How-To</title>
                </subpages>
            </page>
            <page>
                <url>http://example.com/Labs/Social</url>
                <title>Social</title>
            </page>
        </subpages>
    </page>
    <page>
        <url>http://example.com/Tests</url>
        <title>Tests</title>
        <subpages>
            <page>
                <url>http://example.com/Tests/Email</url>
                <title>Email</title>
                <subpages>
                    <page/>
                    <url>http://example.com/Tests/Email/How_to</url>
                    <title>How-To</title>
                </subpages>
            </page>
            <page>
                <url>http://example.com/Tests/Social</url>
                <title>Social</title>
            </page>
        </subpages>
    </page>
</pages>

编码:

// rexml is the XML string read from a URL
from xml.etree import ElementTree as ET
tree = ET.fromstring(rexml)
for node in tree.iter('page'):
    for url in node.iterfind('url'):
        print url.text
    for title in node.iterfind('title'):
        print title.text.encode("utf-8")
    print '-' * 30

输出:

http://example.com/article1
Article1
------------------------------
http://example.com/article1/subarticle1
SubArticle1
------------------------------
http://example.com/article2
Article2
------------------------------
http://example.com/article3
Article3
------------------------------

Xml 表示站点地图的树状结构。

我整天都在文档和谷歌上下,无法弄清楚如何获得条目的节点深度。

我使用了子容器的计数,但这仅适用于第一个父容器,然后它会中断,因为我无法弄清楚如何重置。但这可能只是一个骇人听闻的想法。

所需的输出:

0
http://example.com/article1
Article1
------------------------------
1
http://example.com/article1/subarticle1
SubArticle1
------------------------------
0
http://example.com/article2
Article2
------------------------------
0
http://example.com/article3
Article3
------------------------------
4

6 回答 6

10

Python ElementTreeAPI 为 XML 树的深度优先遍历提供了迭代器——不幸的是,这些迭代器不向调用者提供任何深度信息。

但是您可以编写一个深度优先迭代器,它还返回每个元素的深度信息:

import xml.etree.ElementTree as ET

def depth_iter(element, tag=None):
    stack = []
    stack.append(iter([element]))
    while stack:
        e = next(stack[-1], None)
        if e == None:
            stack.pop()
        else:
            stack.append(iter(e))
            if tag == None or e.tag == tag:
                yield (e, len(stack) - 1)

请注意,这比通过跟随父链接(使用时)确定深度更有效lxml- 即它O(n)O(n log n).

于 2017-01-08T18:19:56.547 回答
5
import xml.etree.ElementTree as etree
tree = etree.ElementTree(etree.fromstring(rexml)) 
maxdepth = 0
def depth(elem, level): 
   """function to get the maxdepth"""
    global maxdepth
    if (level == maxdepth):
        maxdepth += 1
   # recursive call to function to get the depth
    for child in elem:
        depth(child, level + 1) 


depth(tree.getroot(), -1)
print(maxdepth)
于 2020-02-08T21:00:10.007 回答
4

用过lxml.html

import lxml.html

rexml = ...

def depth(node):
    d = 0
    while node is not None:
        d += 1
        node = node.getparent()
    return d

tree = lxml.html.fromstring(rexml)
for node in tree.iter('page'):
    print depth(node)
    for url in node.iterfind('url'):
        print url.text
    for title in node.iterfind('title'):
        print title.text.encode("utf-8")
    print '-' * 30
于 2013-06-24T13:14:12.840 回答
1

我的方法,递归函数来列出级别。您必须首先设置您要传递的节点的初始部门:

# Definition of recursive function
def listchildrens(node,depth):
    # Print node, indent with depth 
    print(" " * depth,"Type",node.tag,"Attributes",node.attrib,"Depth":depth}
    # If node has childs, recall function for the node with existing depth
    if len(node) > 0:
        # Increase depth and recall function
        depth+= 1
        for child in node:
            listchildrens(node,depth)
# Define starting depth
startdepth = 1
# Call the function with the XML body and starting depth
listchildrens(xmlBody,startdepth)
于 2020-12-07T15:54:39.093 回答
0

lxml 最适合这个,但是如果你必须使用标准库,不要使用 iter 并去走树,这样你就可以知道你在哪里。

from xml.etree import ElementTree as ET
tree = ET.fromstring(rexml)

def sub(node, tag):
    return node.findall(tag) or []

def print_page(node, depth):
    print "%s" % depth
    url = node.find("url")
    if url is not None:
        print url.text
    title = node.find("title")
    if title is not None:
        print title.text
    print '-' * 30

def find_pages(node, depth=0):
    for page in sub(node, "page"):
        print_page(page, depth)
        subpage = page.find("subpages")
        if subpage is not None:
            find_pages(subpage, depth+1)

find_pages(tree)
于 2013-06-24T13:25:17.670 回答
-2

这是不使用 XML 库的另一种简单方法:

depth = 0
for i in range(int(input())):
    tab = input().count('    ')
    if tab > depth:
        depth = tab
print(depth)
于 2019-10-26T20:12:41.193 回答