试图用Python解析XML文件 - 我做错了什么?
我正在第一次使用XML和Python。最终目标是向REST服务发送请求,以XML接收响应,并根据返回的内容解析值并发送电子邮件。但是,REST服务还没有到位,所以现在我正在试验保存在我的C盘上的XML文件。试图用Python解析XML文件 - 我做错了什么?
我有一个简单的代码位,我很困惑,为什么它不工作。
这是我的XML文件( “XMLTest.xml”):
<Response>
<exitCode>1</exitCode>
<fileName>C:/Something/</fileName>
<errors>
<error>Error generating report</error>
</errors>
</Response>
这是我到目前为止的代码:
from xml.dom import minidom
something = open("C:/XMLTest.xml")
something = minidom.parse(something)
nodeList = []
for node in something.getElementsByTagName("Response"):
nodeList.extend(t.nodeValue for t in node.childNodes)
print nodeList
但是打印出来的结果是...
[u'\n\t', None, u'\n\t', None, u'\n\t', None, u'\n']
我在做什么错?
我试图让该节点的值。有一个更好的方法吗? Python中是否有内置方法将xml文件转换为对象或字典?我想获得所有的价值,最好是附上名字。
这是否帮助?
doc = '''<Response>
<exitCode>1</exitCode>
<fileName>C:/Something/</fileName>
<errors>
<error>Error generating report</error>
</errors>
</Response>'''
from xml.dom import minidom
something = minidom.parseString(doc)
nodeList = [ ]
for node in something.getElementsByTagName("Response"):
response = { }
response[ "exit code" ] = node.getElementsByTagName("exitCode")[ 0 ].childNodes[ 0 ].nodeValue
response[ "file name" ] = node.getElementsByTagName("fileName")[ 0 ].childNodes[ 0 ].nodeValue
errors = node.getElementsByTagName("errors")[ 0 ].getElementsByTagName("error")
response[ "errors" ] = [ error.childNodes[ 0 ].nodeValue for error in errors ]
nodeList.append(response)
import pprint
pprint.pprint(nodeList)
产生
[{'errors': [u'Error generating report'],
'exit code': u'1',
'file name': u'C:/Something/'}]
这适用于这个特定的例子,但我在寻找一些更通用的东西,可以解析任何xml文件进入某种Python结构...... – froadie 2010-08-26 14:55:17
@froadie:该函数已经存在;它被称为'xml.dom.minidom.parse'。没有可以充分表示XML的内置Python结构,所以它定义了它自己的结构。 – katrielalex 2010-08-26 14:59:01
这是一个很好的解决方案。如果你想要更健壮的东西,你可能希望在xml.dom.minidom中使用'xml.etree.ElementTree',因为它往往涉及嵌套遍历的更少的语法。 – jathanism 2010-08-26 15:16:16
你不是想从DOM的角度来看,XML。即,'C:/ Something'不是标记名为'fileName'的元素的节点值;它是文本节点的nodevalue,它是标记名为'fileName'的元素的第一个子元素。
我建议你做的是在python本身中多玩一点:启动python。 ( ':/ < /文件名> > <响应> <文件名> C')
x.getElementsByTagName
从进口xml.dom的minidom命名X = minidom.parseString
('Response') ... x.getElementsByTagName('Response')[0] .childNodes [0] ...
等等。您将快速了解文档如何被解析。
如果你是刚刚开始使用XML和Python,并没有令人信服的理由使用DOM,我强烈建议你看看ElementTree的API(在标准库中xml.etree.ElementTree实现)
举你一尝:
import xml.etree.cElementTree as etree
tree = etree.parse('C:/XMLTest.xml')
response = tree.getroot()
exitcode = response.find('exitCode').text
filename = response.find('fileName').text
errors = [i.text for i in response.find('errors')]
(如果你需要更多的权力 - 的XPath,验证,XSLT等等 - 你甚至可以切换到lxml,它实现了相同的API,但有很多群众演员)
我推荐我的l文库xml2obj。它比DOM更清洁。 “库”只有84行代码可以嵌入到任何地方。
In [185]: resp = xml2obj(something)
In [186]: resp.exitCode
Out[186]: u'1'
In [187]: resp.fileName
Out[187]: u'C:/Something/'
In [188]: len(resp.errors)
Out[188]: 1
In [189]: for node in resp.errors:
.....: print node.error
.....:
.....:
Error generating report
这就是我期望您发布的代码打印的代码。你想得到什么结果? – katrielalex 2010-08-26 14:41:28
@Katrielalex - 我试图获取节点的值 - 1,“C:/ Something”等。我该如何实现?有没有更好的办法?有没有简单的方法来获得某种字典或对象的节点名称和值? – froadie 2010-08-26 14:45:16
见下文。不幸的是,没有默认的方法将其转换为字典,因为XML太灵活了,因此没有明智的方法。你必须硬连接节点的索引(例如,如果有两个'exitCode'节点会发生什么?) – katrielalex 2010-08-26 14:53:09