如何使用Python遍历XML(使用xml.dom.minidom)测试子节点是否存在
我正在使用Python和xml.dom.minidom来处理一个导出的Excel表格,目的是生成一个我们餐厅菜单的HTML表格。我通过多次调用.write来输出内容。问题在于,Excel输出的XML结构并不规范。为了解决这个问题,我设置了一些变量(比如day、previousDay、meal等),当我遇到某些子节点时,这些变量会被赋值。我使用了一堆if语句来判断什么时候开始一个新的表格(比如每周的每一天),或者什么时候开始新的一行(当day不等于previousDay时)等等。
不过,我在忽略某些特定节点时遇到了困难。Excel输出的有一些节点是我需要忽略的,我可以根据它们的子节点的特定值来判断,但我不知道该怎么实现。
基本上,我需要在我的主循环中加入以下的if语句:
for node in dome.getElementsByTagName('data'):
if node contains childNode with nodeValue == 'test':
do something
3 个回答
0
你有没有考虑过使用SAX解析器呢?SAX解析器会按照节点出现的顺序(深度优先)来处理XML的树形结构,这样你可以在解析的时候直接处理节点的值。
0
你一定要用 xml.dom.minidom
吗?其实,这种情况用 XPath 会更好。比如,使用 lxml.etree
,你可以很方便地找到你想要的所有元素:
my_elements = document.xpath("//data[not(*[.='test'])]")
W3C 的 DOM 在处理实际问题时真的很麻烦,因为它没有一些简单的功能,比如直接返回元素的属性值。(XPath 规定一个元素的值是它所有子文本节点拼接在一起的,这就是上面那个模式能工作的原因。)
你需要实现一个辅助函数来处理这种情况,比如:
def element_text(e):
return "".join(t.nodeValue for t in e.childNodes if t.nodeType == Node.TEXT_NODE)
这样可以更容易地构建一个过滤函数,比如:
def element_is_of_interest(e):
return not any((c for c in e.childNodes if element_text(c) == "test"))
然后你可以这样获取你的元素:
my_elements = filter(element_is_of_interest, d.getElementsByTagName("data"))
0
我觉得可以用一个嵌套的for循环来解决这个问题,里面可以加一个可以跳出的条件(也就是异常处理),像下面这样。
Class BadNodeException (Exception):
pass
for node in dome.getElementsByTagName('data'):
try:
for child in node.childNodes:
if child.nodeValue == 'test':
raise BadNodeException
## process node as normal
except BadNodeException:
pass