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

时间:2011-04-07 17:29:04

标签: python xml minidom

我正在使用Python和xml.dom.minidom迭代导出的Excel电子表格,为我们的餐厅菜单输出HTML表格,并调用.write。困难在于Excel输出的XML不是结构化的。为了弥补这一点,我设置了一些变量(day,previousDay,meal等),当我遇到具有我正在测试的nodeValue的子节点时,这些变量就会被设置。我有一堆if语句来确定何时开始一个新表(一周中的每一天),或一个新行(当天!= previousDay)等等。

我正在努力弄清楚如何忽略特定节点。有一些节点可以从Excel中获取我需要忽略的节点,我可以根据具有特定值的子节点来完成此操作,但我无法弄清楚如何实现它。

基本上,我需要在main for循环中使用以下if语句:

for node in dome.getElementsByTagName('data'):  
    if node contains childNode with nodeValue == 'test':
        do something

3 个答案:

答案 0 :(得分:0)

我很快就会有一个嵌套的for循环,带有一个get-out-of-node-free-card(嗯,异常),如下所示。

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

答案 1 :(得分: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"))

答案 2 :(得分:0)

您是否考虑过使用SAX解析器? Sax解析器按照节点出现的顺序(深度优先)处理XML树结构,并允许您在解析它时处理节点值。

xml.sax.XmlReader

相关问题