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
------------------------------
答案 0 :(得分:5)
Python ElementTree
API提供了深度优先遍历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)
。
答案 1 :(得分: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
答案 2 :(得分:3)
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)
答案 3 :(得分: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)
答案 4 :(得分:0)
lxml最适合这个,但是如果你必须使用标准库,不要使用它并走树,这样你就可以知道你在哪里。
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)
答案 5 :(得分:0)
这是无需使用XML库的另一种简单方法:
depth = 0
for i in range(int(input())):
tab = input().count(' ')
if tab > depth:
depth = tab
print(depth)