Python: 解析一个XML文件,一个节点有多个属性

Python: Parsing an XML file with several attributes in one node

我在编程方面还是个新手,但我知道一些 Python 并且总体上熟悉 XPath 和 XML。目前我正在处理一些看起来像这样的 XML 数据:

<foo>
  <bar>
      <unit>
          <structure>
              <token word="Rocky" att1="noun" att2="name">Rocky</token>
              <token word="the" att1="article" att2="">the</token>
              <token word="yellow" att1="adjective" att2="color">yellow</token>
              <token word="dog" att1="noun" att2="animal">dog</token>
          </structure>
      </unit>
  </bar>
</foo>

现在我要做的就是先找到一个属性值,让我们取

<token word="dog" att1="noun"att2="animal"</token>

举个例子。因此,在文档中的所有结构中,我想首先找到所有具有 animal 作为 att2 值的节点,然后获取所有的兄弟节点将该节点放入列表中。因为每个节点都有几个属性,所以我试图将它们中的每一个都包含到一个不同的列表中,也就是说,从具有 animal[=27 的结构中的所有属性中列出一个列表=] 在其孩子的 att2 值之一中。例如:

 listWord = [Rocky, the, yellow, dog]
 listAtt1 = [noun, article, adjective, noun]
 listAtt2 = [name, ,color, animal]

目前我只是想知道这是否可能。到目前为止,我只是设法用属性结构撞墙,更不用说空值了。

包含结束令牌标签,并假设您的文本包含在 test.xml 中,以下内容:

import xml.etree.ElementTree

e = xml.etree.ElementTree.parse('test.xml').getroot()

listWord = []
listAtt1 = []
listAtt2 = []

for child in e.iter('token'):
    listWord.append(child.attrib['word'])
    listAtt1.append(child.attrib['att1'])
    listAtt2.append(child.attrib['att2'])

print listWord
print listAtt1
print listAtt2

将return:

['Rocky', 'the', 'yellow', 'dog']
['noun', 'article', 'adjective', 'noun']
['name', '', 'color', 'animal']

e.iter() 允许您迭代 e 作为根及其下方的元素 - 我们将 token 的标签指定为仅 return token 元素. child.attrib return 是一个属性字典,我们将其附加到列表中。

编辑:对于你问题的第二部分,我认为以下内容(虽然可能不是最佳实践)将满足你的要求:

import xml.etree.ElementTree

e = xml.etree.ElementTree.parse('test.xml').getroot()

listWord = []
listAtt1 = []
listAtt2 = []
animal_structs =[]

for structure in e.iter('structure'):
    for child in structure.iter('token'):
        if 'att2' in child.keys():
            if child.attrib['att2'] == 'animal':
                animal_structs.append(structure)
                break

for structure in animal_structs:
    for child in structure.iter('token'):
        listWord.append(child.attrib['word'])
        listAtt1.append(child.attrib['att1'])
        listAtt2.append(child.attrib['att2'])

print listWord
print listAtt1
print listAtt2

我们首先创建一个包含所有 structure 元素和 animal 子元素的列表,然后 return 每个结构的所有 then 属性。

我不确定我理解你的问题,但以下是我理解的部分(使用 lxml 和 xpath):

from lxml import etree
tree = etree.fromstring("""<foo>
  <bar>
      <unit>
          <structure>
              <token word="Rocky" att1="noun" att2="name"></token>
              <token word="the" att1="article" att2=""></token>
              <token word="yellow" att1="adjective" att2="color"></token>
              <token word="dog" att1="noun" att2="animal"></token>
          </structure>
      </unit>
  </bar>
</foo>""")


// get a list of all possible words, att1, att2:
listWord = tree.xpath("//token/@word")
listAtt1 = tree.xpath("//token/@att1")
listAtt2 = tree.xpath("//token/@att2")

// get all the tokens with att2="animal"
for token in tree.xpath('//token[@att2="animal"]'):
    do_your_own_stuff()