使用 minidom python 从父标签 xml 打印值

print value from a parent tag xml with minidom python

我有一个非常大的 xml 文件,如果某些标签超过 2 个,我需要知道 ID 值。 xml 文件是这样的:

<Users>
    <Calendar ID="text1">
        <Folders>...</Folders>
        <FolderRights/>
        <Event/>
        <EventReminder/>
        <EventContact/>
        <EventRecurrence/>
        <EventException/>
        <ContactItem>
            <COLUMNS>...</COLUMNS>
            <FIELDS>...</FIELDS>
            <FIELDS>...</FIELDS>
            <FIELDS>...</FIELDS>
            <FIELDS>...</FIELDS>
        </ContactItem>
        <ContactLocation>...</ContactLocation>
        <Tags/>
        <TagLinks/>
        <ItemAttr/>
        <ItemAttrData/>
    </Calendar>
    <Calendar ID="text2">
        <Folders>...</Folders>
        <FolderRights/>
        <Event/>
        <EventReminder/>
        <EventContact/>
        <EventRecurrence/>
        <EventException/>
        <ContactItem/>
        <ContactLocation/>
        <Tags/>
        <TagLinks/>
        <ItemAttr/>
        <ItemAttrData/>
    </Calendar>
</Users>

如果 Contact 中的 FIELDS 大于 2,我必须在每个 Calendar 标签的 ID 内打印文本,所以我写了这段代码:

from xml.dom.minidom import parseString
xmlFile = open('prova.xml','r')
data = xmlFile.read()
xmlFile.close()
dom = parseString(data)
for contatti in dom.getElementsByTagName('ContactItem'):
    if (len(contatti.getElementsByTagName('FIELDS')) > 2):
        print (contatti.getElementsByTagName('Calendar')[0].firstChild.nodeValue)

但我没有 ID 值。 我怎样才能做到这一点?非常感谢

假设您获得了正确的标记元素,这是访问 ID 属性的方法:

for contatti in dom.getElementsByTagName('Users'):
    calendars = contatti.getElementsByTagName('Calendar')
    for calendar in calendars:
         attribute = calendar.attributes.get("ID")
         print attribute.name
         print attribute.value

使用 lxml 非常简单,使用 count:

找到具有 > 2 contactitem//fields 标签的日历父标签
from lxml.html import fromstring

tree = fromstring(the_xml)

print(tree.xpath("//calendar[count(./contactitem//fields) > 2]/@id"))

样本运行:

In [8]: from lxml.html import fromstring

In [9]: tree = fromstring(h)

In [10]: tree.xpath("//calendar[count(./contactitem//fields) > 2]/@id"
   ....: )
Out[10]: ['text1']

或使用lxml.etree:

from lxml.etree import fromstring

tree = fromstring(h)

print(tree.xpath("//Calendar[count(./ContactItem//FIELDS) > 2]/@ID"))

要从文件中读取,请使用 parse:

from lxml.html import parse
tree = parse("your.xml")

您通常应该从文件中读取并让 lxml 处理编码。

count 在 xml.etree 中不受支持,因此要执行相同的操作,您可以使用 findall:

from xml.etree import ElementTree as et

tree = et.parse("Your.xml")
cals = tree.findall(".//Calendar") 
print([c.get("ID") for c in cals if len(c.findall("./ContactItem/FIELDS")) > 2])