Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中解析XML:在子节点具有特定属性的情况下选择属性_Python_Xml - Fatal编程技术网

在python中解析XML:在子节点具有特定属性的情况下选择属性

在python中解析XML:在子节点具有特定属性的情况下选择属性,python,xml,Python,Xml,给定xml xmlstr = ''' <myxml> <Description id="10"> <child info="myurl"/> </Description> </myxml>' 并将查找更改为//Description/[child[@info]] 两者都返回以下错误: SyntaxError: invalid predicate 我知道etree只支持xpath的一个子集,但这似乎并不是特

给定xml

xmlstr = '''
<myxml>
    <Description id="10">
      <child info="myurl"/>
    </Description>
</myxml>'
并将查找更改为
//Description/[child[@info]]

两者都返回以下错误:

SyntaxError: invalid predicate
我知道etree只支持xpath的一个子集,但这似乎并不是特别奇怪——这应该起作用吗?如果是,我做错了什么

将查找更改为
//Description/[child]
会起作用,并返回

{'id': '10'}

正如预期的那样

您肯定达到了XPath有限支持的限制,因为如果我们直接查看(查看3.7源代码),我们可以看到在解析元素路径表达式时,只考虑过滤器中的以下内容:

  • [@attribute]
    谓词
  • [@attribute='value']
  • [tag]
  • [.='value']
    [tag='value']
  • [index]
    [last()]
    [last()-index]
这意味着这两个相当简单的表达式都不受支持



如果你真的想/需要坚持使用内置的
ElementTree
库,解决这个问题的一种方法是通过
.findall()
查找所有
Description
标记,并过滤带有
info
属性的
子元素的标记。

你也可以将这些值作为键,这使得收集数据的方法更加结构化:

import xml.etree.ElementTree as ET
root = ET.fromstring(xmlstr)
wht =root.find(".//Description") 
wht.keys() #--> ['id']
wht.get('id')  # --> '10'

我不需要坚持使用
ElementTree
-我也尝试过lxml,但发现使用它稍微不那么直观…@ChrisW是的,使用
lxml
,您的表达式
//Description[child/@info]/@id
将按原样工作。还有
BeautifulSoup
,这可能是一个更直观的选择。过来看。谢谢。是的,即使想要为属性指定一个特定的值,也可以使用lxml:
root.xpath(“//Description[child/@info='myurl']”)
:)@ChrisW它绝对是一个强大的工具。而且,速度快得惊人!
import xml.etree.ElementTree as ET
root = ET.fromstring(xmlstr)
wht =root.find(".//Description") 
wht.keys() #--> ['id']
wht.get('id')  # --> '10'