Minidom getElementById 不起作用

7 投票
5 回答
6183 浏览
提问于 2025-04-18 12:37

Minidom的getElementById函数对我传入的任何内容都返回None。

比如,这段代码:

l = minidom.parseString('<node id="node">Node</node>')
print(l.getElementById("node"))

在我的电脑上打印出"None"。

我一定是哪里做错了,但我就是搞不明白!

我在用Python 3.3.2,如果这有帮助的话。

5 个回答

0

每次你通过ID查找一个元素时,如果都要遍历文档中的每一个节点,这样做可能会非常耗时,而且浪费资源。

你可以只用一次这个代码来解决这个问题:

import xml.dom.minidom as dom
xml = dom.parse("my_file.xml")

# Parse every element and set the ID attribute
for nodes in xml.getElementsByTagName("*"):
    nodes.setIdAttribute("id")

# Now this works (and it is efficient)
test = xml.getElementById("some_id")
0

在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。这些问题可能会让我们感到困惑,不知道该怎么解决。比如,有人可能在使用某个特定的功能时,发现它没有按照预期工作,或者出现了错误信息。这种情况下,通常我们可以通过查阅相关的文档、论坛或者问其他人来找到解决办法。

在StackOverflow上,很多人会分享他们遇到的问题和解决方案。这里的讨论通常会涉及到一些代码示例,帮助大家更好地理解问题所在。通过这些交流,编程小白也能逐渐掌握一些常见的技巧和知识,提升自己的编程能力。

总之,遇到问题时,不要害怕寻求帮助,利用好网络资源,和其他开发者交流,都是很好的学习方式。

def getElementById(doc, _id):
    for c in doc.childNodes:
        if c.nodeType not in [c.DOCUMENT_NODE, c.TEXT_NODE, c.DOCUMENT_TYPE_NODE, c.COMMENT_NODE]:
        #[ATTRIBUTE_NODE, CDATA_SECTION_NODE, ENTITY_NODE, PROCESSING_INSTRUCTION_NODE, NOTATION_NODE
            if c.getAttribute('id') == _id:
                return c
        res_for_c = getElementById(c, _id)
        if res_for_c:
            return res_for_c
    return None
1

根据你输入的指令,我明白你是想找到一个元素,它的 id 值是 node

解决方法是遍历你所有的 XML 元素(在这个情况下你只有一个元素,但这没关系),然后检查这个元素是否有一个叫 id 的属性,并且这个属性的值是否是 node

现在我们把这个逻辑转化成一个程序:

>>> from xml.dom import minidom
>>> xml_string = '<node id="node">Node</node>'
>>> xml_doc = minidom.parseString(xml_string)
>>> elements = xml_doc.getElementsByTagName('node')
>>> for element in elements:
...     if element.hasAttribute('id') and element.getAttribute('id') == 'node':
...             print(element.toxml())
... 
<node id="node">Node</node>
3

我用了一种不同的方法来通过ID获取元素(这里的ID指的是XML中的“id”属性),因为我只想使用 xml.dom.minidom.

下面是我工作中的一个例子:

#import minidom
from xml.dom.minidom import parse as p
#parse your XML-document
cmmn_doc = p("document.xml")
#Get all child nodes of your root-element or any element surrounding your "target" (in my example "cmmn:casePlanModel")
notelist = cmmn_doc.getElementsByTagName("cmmn:casePlanModel")[0].childNodes

#Now find the element via the id-tag
def find_element(id):
    i=0
    for i in range(len(notelist)):
        if notelist[i].getAttribute("id") == id:
        return notelist[i].nodeName #(or whatever you want to do)

#Call find_element with the id you are looking for
find_element(id)

这个例子中的XML内容:

    <cmmn:casePlanModel id="CasePlanModel_1" name="A CasePlanModel">
      <cmmn:planItem id="PlanItem_1" definitionRef="Task_1" />
      <cmmn:planItem id="PlanItem_08uai3q" definitionRef="HumanTask_0pgsk2i" />
      <cmmn:planItem id="PlanItem_0crahv8" definitionRef="HumanTask_0jvecsr">
        <cmmn:itemControl id="PlanItemControl_0tdwp8g">
          <cmmn:repetitionRule id="RepetitionRule_03ky93m" />
          <cmmn:requiredRule id="RequiredRule_1klzaio" />
          <cmmn:manualActivationRule id="ManualActivationRule_1rek2bf" />
        </cmmn:itemControl>
      </cmmn:planItem>
      <cmmn:planItem id="PlanItem_08kswcr" definitionRef="HumanTask_14zxi11" />
      <cmmn:planItem id="PlanItem_12b1nkx" definitionRef="ProcessTask_10xuu3g">
        <cmmn:exitCriterion id="EntryCriterion_09gio4l" sentryRef="Sentry_0hst9b5" />
      </cmmn:planItem>
      <cmmn:planItem id="PlanItem_1v34h5m" definitionRef="CaseTask_0hwjce3">
        <cmmn:entryCriterion id="EntryCriterion_1j8r6j1" sentryRef="Sentry_1ii8w5d" />
      </cmmn:planItem>
      <cmmn:planItem id="PlanItem_0wroqsx" definitionRef="EventListener_17yxe7z" />
      <cmmn:sentry id="Sentry_0hst9b5" />
      <cmmn:sentry id="Sentry_1ii8w5d">
        <cmmn:planItemOnPart id="PlanItemOnPart_1gt5jrc" sourceRef="PlanItem_12b1nkx">        <cmmn:standardEvent>complete</cmmn:standardEvent>
</cmmn:planItemOnPart>
        <cmmn:planItemOnPart id="PlanItemOnPart_01b6uw3" sourceRef="PlanItem_0wroqsx">        <cmmn:standardEvent>occur</cmmn:standardEvent>
</cmmn:planItemOnPart>
      </cmmn:sentry>
      <cmmn:task id="Task_1" name="Simple Task" />
      <cmmn:humanTask id="HumanTask_0pgsk2i" name="Human Task" />
      <cmmn:humanTask id="HumanTask_0jvecsr" name="Human_Blocking" isBlocking="false" />
      <cmmn:humanTask id="HumanTask_14zxi11" name="Human_mit_Anhang">
        <cmmn:planningTable id="PlanningTable_1yxv7gm">
          <cmmn:discretionaryItem id="DiscretionaryItem_0ne79yh" definitionRef="DecisionTask_1ecc5v8" />
        </cmmn:planningTable>
      </cmmn:humanTask>
      <cmmn:decisionTask id="DecisionTask_1ecc5v8" name="Descritionary to Human Task" />
      <cmmn:processTask id="ProcessTask_10xuu3g" name="Prozess Task" />
      <cmmn:caseTask id="CaseTask_0hwjce3" name="Case Task" />
      <cmmn:eventListener id="EventListener_17yxe7z" name="EventListener" />
    </cmmn:casePlanModel>

我觉得这种方法更方便。

1

如果你想获取名称为"node"的元素

l.getElementsByTagName("node")

如果你想获取具有属性"id"且值为"node"的元素,可以使用xpath

import xpath
xpath.find("//*['id=node']",l) #search for all elements with an attribute id="node"

撰写回答