我在XML中有很多行,我试图获得一个特定节点属性的实例。

<foo>
   <bar>
      <type foobar="1"/>
      <type foobar="2"/>
   </bar>
</foo>

我如何访问属性foobar的值?在这个例子中,我想要“1”和“2”。


当前回答

我推荐ElementTree。同样的API还有其他兼容的实现,比如lxml和Python标准库中的cElementTree;但是,在这种情况下,他们主要增加的是更快的速度——编程的容易程度取决于ElementTree定义的API。

首先从XML中构建一个Element实例根,例如使用XML函数,或者通过解析文件,例如:

import xml.etree.ElementTree as ET
root = ET.parse('thefile.xml').getroot()

或者在ElementTree中显示的许多其他方法中的任何一种。然后这样做:

for type_tag in root.findall('bar/type'):
    value = type_tag.get('foobar')
    print(value)

输出:

1
2

其他回答

为了增加另一种可能性,可以使用untangle,因为它是一个简单的xml-to-python-object库。这里有一个例子:

安装:

pip install untangle

用法:

你的XML文件(有一点变化):

<foo>
   <bar name="bar_name">
      <type foobar="1"/>
   </bar>
</foo>

使用untangle访问属性:

import untangle

obj = untangle.parse('/path_to_xml_file/file.xml')

print obj.foo.bar['name']
print obj.foo.bar.type['foobar']

输出将是:

bar_name
1

更多关于untangle的信息可以在“untangle”中找到。

此外,如果您感兴趣,可以在“Python和XML”中找到使用XML和Python的工具列表。您还将看到前面的答案中提到的最常见的问题。

这里有一个使用cElementTree的非常简单但有效的代码。

try:
    import cElementTree as ET
except ImportError:
  try:
    # Python 2.5 need to import a different module
    import xml.etree.cElementTree as ET
  except ImportError:
    exit_err("Failed to import cElementTree from any known place")      

def find_in_tree(tree, node):
    found = tree.find(node)
    if found == None:
        print "No %s in file" % node
        found = []
    return found  

# Parse a xml file (specify the path)
def_file = "xml_file_name.xml"
try:
    dom = ET.parse(open(def_file, "r"))
    root = dom.getroot()
except:
    exit_err("Unable to open and parse input definition file: " + def_file)

# Parse to find the child nodes list of node 'myNode'
fwdefs = find_in_tree(root,"myNode")

这是来自“python xml解析”。

Minidom是最快速且非常直接的方法。

XML:

<data>
    <items>
        <item name="item1"></item>
        <item name="item2"></item>
        <item name="item3"></item>
        <item name="item4"></item>
    </items>
</data>

Python:

from xml.dom import minidom

dom = minidom.parse('items.xml')
elements = dom.getElementsByTagName('item')

print(f"There are {len(elements)} items:")

for element in elements:
    print(element.attributes['name'].value)

输出:

There are 4 items:
item1
item2
item3
item4

我很受伤,没有人建议熊猫。Pandas有一个read_xml()函数,它非常适合这种扁平的xml结构。

import pandas as pd

xml = """<foo>
   <bar>
      <type foobar="1"/>
      <type foobar="2"/>
   </bar>
</foo>"""

df = pd.read_xml(xml, xpath=".//type")
print(df)

输出:

   foobar
0       1
1       2

如果源文件是一个xml文件,就像这个示例一样

<pa:Process xmlns:pa="http://sssss">
        <pa:firsttag>SAMPLE</pa:firsttag>
    </pa:Process>

您可以尝试下面的代码

from lxml import etree, objectify
metadata = 'C:\\Users\\PROCS.xml' # this is sample xml file the contents are shown above
parser = etree.XMLParser(remove_blank_text=True) # this line removes the  name space from the xml in this sample the name space is --> http://sssss
tree = etree.parse(metadata, parser) # this line parses the xml file which is PROCS.xml
root = tree.getroot() # we get the root of xml which is process and iterate using a for loop
for elem in root.getiterator():
    if not hasattr(elem.tag, 'find'): continue  # (1)
    i = elem.tag.find('}')
    if i >= 0:
        elem.tag = elem.tag[i+1:]

dict={}  # a python dictionary is declared
for elem in tree.iter(): #iterating through the xml tree using a for loop
    if elem.tag =="firsttag": # if the tag name matches the name that is equated then the text in the tag is stored into the dictionary
        dict["FIRST_TAG"]=str(elem.text)
        print(dict)

输出将是

{'FIRST_TAG': 'SAMPLE'}