2

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

我很难弄清楚如何忽略特定节点。我需要忽略一些从 Excel 获取输出的节点,我可以根据它们具有特定值的子节点来执行此操作,但我不知道如何实现它。

基本上,我的主 for 循环中需要以下 if 语句:

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

3 回答 3

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"))
于 2011-04-07T18:59:36.423 回答
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
于 2011-04-07T17:44:03.133 回答
0

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

xml.sax.XmlReader

于 2011-08-18T18:50:10.363 回答