Minidom getElementById не работает
Функция getElementById Minidom возвращает None для любой записи, которую я передаю ей.
Например, этот код:
l = minidom.parseString('<node id="node">Node</node>')
print(l.getElementById("node"))
Печатает "Нет" на моем компьютере.
Должно быть, я что-то здесь не так делаю, но не могу понять!
Я использую Python 3.3.2, если это поможет.
5 ответов
Если вы хотите получить элементы с именем ="узел"
l.getElementsByTagName("node")
Если вы хотите получить элементы с атрибутом, имеющим атрибут "id" со значением "node", используйте xpath:
import xpath
xpath.find("//*['id=node']",l) #search for all elements with an attribute id="node"
Я использовал другой подход, чтобы получить Elemnts по идентификатору (имеется в виду 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>
Я нашел этот способ более удобным.
Из инструкции, которую вы набрали, я понимаю, что вы пытаетесь получить элемент, который 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>
Перебор всех узлов документа каждый раз, когда вы ищете элемент по идентификатору, может оказаться очень долгим и пустой тратой ресурсов.
Вы можете сделать это только один раз с помощью этого кода:
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")
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