【问题标题】:How to parse xml in python?如何在python中解析xml?
【发布时间】:2014-07-05 01:03:03
【问题描述】:

我必须从 XML 文档中提取 friendlyName

这是我目前的解决方案:

root = ElementTree.fromstring(urllib2.urlopen(XMLLocation).read())        
for child in root.iter('{urn:schemas-upnp-org:device-1-0}friendlyName'):
    return child.text

我有没有更好的方法来做到这一点(也许任何其他不涉及迭代的方法)?我可以使用 XPath 吗?


XML 内容:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
   <specVersion>
      <major>1</major>
      <minor>0</minor>
   </specVersion>
   <device>
      <dlna:X_DLNADOC xmlns:dlna="urn:schemas-dlna-org:device-1-0">DMR-1.50</dlna:X_DLNADOC>
      <deviceType>urn:schemas-upnp-org:device:MediaRenderer:1</deviceType>
      <friendlyName>My Product 912496</friendlyName>
      <manufacturer>embedded</manufacturer>
      <manufacturerURL>http://www.embedded.com</manufacturerURL>
      <modelDescription>Product</modelDescription>
      <modelName>Product</modelName>
      <modelNumber />
      <modelURL>http://www.embedded.com</modelURL>
      <UDN>uuid:93b2abac-cb6a-4857-b891-002261912496</UDN>
      <serviceList>
         <service>
            <serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType>
            <serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId>
            <SCPDURL>/xml/ConnectionManager.xml</SCPDURL>
            <eventSubURL>/Event/org.mpris.MediaPlayer2.mansion/RygelSinkConnectionManager</eventSubURL>
            <controlURL>/Control/org.mpris.MediaPlayer2.mansion/RygelSinkConnectionManager</controlURL>
         </service>
         <service>
            <serviceType>urn:schemas-upnp-org:service:AVTransport:1</serviceType>
            <serviceId>urn:upnp-org:serviceId:AVTransport</serviceId>
            <SCPDURL>/xml/AVTransport2.xml</SCPDURL>
            <eventSubURL>/Event/org.mpris.MediaPlayer2.mansion/RygelAVTransport</eventSubURL>
            <controlURL>/Control/org.mpris.MediaPlayer2.mansion/RygelAVTransport</controlURL>
         </service>
         <service>
            <serviceType>urn:schemas-upnp-org:service:RenderingControl:3</serviceType>
            <serviceId>urn:upnp-org:serviceId:RenderingControl</serviceId>
            <SCPDURL>/xml/RenderingControl2.xml</SCPDURL>
            <eventSubURL>/Event/org.mpris.MediaPlayer2.mansion/RygelRenderingControl</eventSubURL>
            <controlURL>/Control/org.mpris.MediaPlayer2.mansion/RygelRenderingControl</controlURL>
         </service>
         <service>
            <serviceType>urn:schemas-embedded-com:service:RTSPGateway:1</serviceType>
            <serviceId>urn:embedded-com:serviceId:RTSPGateway</serviceId>
            <SCPDURL>/xml/RTSPGateway.xml</SCPDURL>
            <eventSubURL>/Event/org.mpris.MediaPlayer2.mansion/RygelRTSPGateway</eventSubURL>
            <controlURL>/Control/org.mpris.MediaPlayer2.mansion/RygelRTSPGateway</controlURL>
         </service>
         <service>
            <serviceType>urn:schemas-embedded-com:service:SpeakerManagement:1</serviceType>
            <serviceId>urn:embedded-com:serviceId:SpeakerManagement</serviceId>
            <SCPDURL>/xml/SpeakerManagement.xml</SCPDURL>
            <eventSubURL>/Event/org.mpris.MediaPlayer2.mansion/RygelSpeakerManagement</eventSubURL>
            <controlURL>/Control/org.mpris.MediaPlayer2.mansion/RygelSpeakerManagement</controlURL>
         </service>
         <service>
            <serviceType>urn:schemas-embedded-com:service:NetworkManagement:1</serviceType>
            <serviceId>urn:embedded-com:serviceId:NetworkManagement</serviceId>
            <SCPDURL>/xml/NetworkManagement.xml</SCPDURL>
            <eventSubURL>/Event/org.mpris.MediaPlayer2.mansion/RygelNetworkManagement</eventSubURL>
            <controlURL>/Control/org.mpris.MediaPlayer2.mansion/RygelNetworkManagement</controlURL>
         </service>
      </serviceList>
      <iconList>
         <icon>
            <mimetype>image/png</mimetype>
            <width>120</width>
            <height>120</height>
            <depth>32</depth>
            <url>/org.mpris.MediaPlayer2.mansion-120x120x32.png</url>
         </icon>
         <icon>
            <mimetype>image/png</mimetype>
            <width>48</width>
            <height>48</height>
            <depth>32</depth>
            <url>/org.mpris.MediaPlayer2.mansion-48x48x32.png</url>
         </icon>
         <icon>
            <mimetype>image/jpeg</mimetype>
            <width>120</width>
            <height>120</height>
            <depth>24</depth>
            <url>/org.mpris.MediaPlayer2.mansion-120x120x24.jpg</url>
         </icon>
         <icon>
            <mimetype>image/jpeg</mimetype>
            <width>48</width>
            <height>48</height>
            <depth>24</depth>
            <url>/org.mpris.MediaPlayer2.mansion-48x48x24.jpg</url>
         </icon>
      </iconList>
      <X_embeddedDevice xmlns:edd="schemas-embedded-com:extended-device-description">
         <firmwareVersion>v1.0 (4.155.1.15.002)</firmwareVersion>
         <features>
            <feature>
               <name>com.sony.Product</name>
               <version>1.0.0</version>
            </feature>
            <feature>
               <name>com.sony.Product.btmrc</name>
               <version>1.0.0</version>
            </feature>
            <feature>
               <name>com.sony.Product.btmrs</name>
               <version>1.0.0</version>
            </feature>
         </features>
      </X_embeddedDevice>
   </device>
</root>

【问题讨论】:

  • find() 应该可以解决问题。
  • @PedroRomano 如果我这样给出 a = root.find('friendlyName') 然后 a.text 它给出 None
  • 你可以在下面看到我的答案,你可以使用 find 或 xpath

标签: python xml python-2.7 xpath xml-parsing


【解决方案1】:

使用 ElementTree,您可以直接从文件中读取或将其加载到字符串中。

首先,包括以下导入。

from xml.etree.ElementTree import ElementTree
from xml.parsers.expat import ExpatError

如果你使用的是字符串:

from xml.etree.ElementTree import fromstring
try:
tree = fromstring(xml_data)
except ExpatData:
print "Unable to parse XML data from string"

否则直接加载:

try:
tree = ElementTree(file = "filename")
except ExpatData:
print "Unable to parse XML from file"

初始化树后,您就可以开始解析信息了。

root = tree.getroot()
print root.find('device/friendlyName').text

【讨论】:

  • 我在这里使用 XML 的位置,那么你的代码需要改变什么
  • 在你的代码中我已经使用了 ET.parse(XMLLocation) 但这给出了错误
  • 我正在寻找一种将 xml 内容放入字符串变量以避免错误的方法
【解决方案2】:

佩德罗,在 cmets 中是对的。

.find(match, namespaces=None)

找到第一个匹配的子元素。 match 可以是标签名称或路径。返回一个元素实例或无。 namespaces 是从命名空间前缀到全名的可选映射。

ElemntTree 文档在这些情况下非常有用。 https://docs.python.org/3/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.find

编辑: 我在 cmets 中给出的链接指向以下代码:

import xml.etree.ElementTree as ET
input = '''<stuff>
<users>
<user x="2">
<id>001</id>
<name>Chuck</name>
</user>
<user x="7">
<id>009</id>
<name>Brent</name>
</user>
</users>
</stuff>
'''
stuff = ET.fromstring(input)
lst = stuff.findall("users/user")
print len(lst)
for item in lst:
print item.attrib["x"]
item = lst[0]
ET.dump(item)
item.get("x")   # get works on attributes
item.find("id").text
item.find("id").tag
for user in stuff.getiterator('user') :
print "User" , user.attrib["x"]
ET.dump(user)

上面的代码使用:

item.find("id").text

如果您修改它,同时删除您不需要的其他代码...查找应该如下所示:

item.find('device/friendlyName').text

您可以获取 xml 文件,而不是使用带有以下内容的输入字符串(来自 ElementTree 文档):

import xml.etree.ElementTree as ET
tree = ET.parse('your_file_name.xml')

【讨论】:

  • dr-chuck.com/csev-blog/2008/09/… 试试这个网页,那里有一个例子说明它是如何使用的
  • 在该示例中,将整个 xml 作为输入,但在我的代码中我必须将其位置作为输入,那么我该如何修改我的代码呢?
  • 我已经参考你的代码编辑了我的代码,但我仍然无法获得友好名称,你能否给我确切的代码,并且必须检查它是否符合我给定的 xml
  • 我认为 xmlns 给我带来了问题
  • 你用的是哪个版本的python?
【解决方案3】:
import xml.etree.ElementTree as ElementTree

namespace = '{urn:schemas-upnp-org:device-1-0}'
root = ElementTree.fromstring(urllib2.urlopen(XMLLocation).read())

# The `//` specifies all subelements within the whole tree.
return root.find('.//{}friendlyName'.format(namespace)).text

find() 函数在找到第一个匹配项时停止。要获取与 XPath 匹配的所有元素,请使用 findall() 函数。

【讨论】:

    猜你喜欢
    • 2017-09-29
    • 2012-12-26
    • 2018-01-27
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多