如何从python中提取xml值@ attribute = something

时间:2013-01-11 19:43:23

标签: python xml extract etl

例如,这是我的xml

<p1>
     <p2>
         <name>nikki</name>
         <p3>
            <c days="1">1</c>
            <c days="3">5</c>
            <c days="7">9</c>
        </p3>
    </p2>
</p1>

到目前为止,我能够使用name = etree.XPath('/p1/p2/name/text()')(root)[0]提取名称但是如何提取day1,day3和day7以获得值1,5,7?

这是使用import etree

的代码
name = etree.XPath('/p1/p2/name/text()')(root)[0]

?? day1 = etree.XPath('/p1/p2/p3/c@days="1"/text()')(root)[0]
?? day3 = etree.XPath('/p1/p2/p3/c@days="3"/text()')(root)[0]
?? day7 = etree.XPath('/p1/p2/p3/c@days="7"/text()')(root)[0]

print name , day1 , day2, day7 


OUTPUT WANTED: nikki 1 5 9

4 个答案:

答案 0 :(得分:2)

ElementTree Element的text属性将为您提供元素标签之间的值。所以:

print name, day1.text, day2.text, day7.text

应该给你预期的输出。

Here是ElementTree Element的文档。

答案 1 :(得分:0)

您似乎正在使用lxml。这是一个建议:

from lxml import etree

XML ="""
<p1>
     <p2>
         <name>nikki</name>
         <p3>
            <c days="1">1</c>
            <c days="3">5</c>
            <c days="7">9</c>
        </p3>
    </p2>
</p1>"""

root = etree.fromstring(XML)

name = root.xpath("p2/name")[0]
p3 = root.xpath("p2/p3")[0]
day1 = p3.xpath('c[@days="1"]')[0]
day3 = p3.xpath('c[@days="3"]')[0]
day7 = p3.xpath('c[@days="7"]')[0]

print name.text, day1.text, day3.text, day7.text 

输出:

nikki 1 5 9

注意predicates(方括号中的过滤器表达式)。

问题中的'/p1/p2/p3/c@days="7"/text()'等表达式无效。

答案 2 :(得分:0)

from xml.dom.minidom import parseString

_f = open("your_file_path.xml", "r")
data = _f.read()
_f.close()
dom = parseString(data)

# name
name = dom.getElementsByTagName('name')[0].firstChild.data

# days
itemList = dom.getElementsByTagName("c")
for s in itemList:
    print s.attributes['days'].value

or 

day1 = dom.getElementsByTagName("c")[0].firstChild.nodeValue

or 

day1 = dom.getElementsByTagName("c")[0].firstChild.data

答案 3 :(得分:0)

尝试使用lxml,它有更好的xpath支持,你正在过度思考:

xml=\
"""<p1>
     <p2>
         <name>nikki</name>
         <p3>
            <c days="1">1</c>
            <c days="3">5</c>
            <c days="7">9</c>
        </p3>
    </p2>
</p1>"""
import lxml.etree as et
doc=et.fromstring(xml)
print doc.xpath('.//name/text()|.//c/text()')

出:

['nikki', '1', '5', '9']

编辑:如果你必须使用标准的lib,你可以这样做:

print root.find('.//name').text
print [e.text for e in root.findall('.//c')]

出:

nikki
['1', '5', '9']