如何使用Python遍历XML(使用xml.dom.minidom)测试子节点是否存在

2 投票
3 回答
3771 浏览
提问于 2025-04-16 15:17

我正在使用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的树形结构,这样你可以在解析的时候直接处理节点的值。

xml.sax.XmlReader

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

撰写回答