【问题标题】:Invalid Predicate When Parsing XCode解析 XCode 时谓词无效
【发布时间】:2013-07-02 00:47:16
【问题描述】:

我正在使用 ElementTree 解析下面显示的 xml,但在代码中出现错误 Invalid Predicate

基本上,我试图找到具有特定 pin 属性名称的元素 connect

XML

<deviceset>
<devices>
<device name="">
<connects>
<connect gate="G$1" pin="+15V_DC" pad="7"/>
<connect gate="G$1" pin="FB" pad="3"/>
<connect gate="G$1" pin="ICOM" pad="4"/>
<connect gate="G$1" pin="IN+" pad="5"/>
<connect gate="G$1" pin="IN-" pad="6"/>
<connect gate="G$1" pin="OUT_HI" pad="1"/>
<connect gate="G$1" pin="OUT_LO" pad="9"/>
<connect gate="G$1" pin="PWRCOM" pad="2"/>
</connects>
</device>
</devices>
</deviceset>

Python代码

  # Imports
    import xml.etree as ET
    from xml.etree.ElementTree import Element, SubElement, Comment, tostring

    # Open a file sent to the function
    file = open(os.path.join(__location__, file));
    tree = ET.parse(file)
    root = tree.getroot()
    deviceset = root.find ('deviceset')
    deviceset.find('devices').find('device').find('connects').**findall("./connect[@pin = \"FB\"]")**

问题似乎是 XPATH 样式路径(上面突出显示)。

关于我做错了什么有什么想法吗?

【问题讨论】:

  • 无论你是2.x还是3.x,都没有xml.etree.parse这样的功能。你的意思是from xml.etree import ElementTree as ET?最重要的是,您发布的代码甚至会在运行之前引发缩进错误。您能否给我们实际的、可运行的代码来显示您的错误?这使得调试变得容易得多。
  • 另外,ElementTree 不会在这个 XML 中给你任何这样的错误,因为它会放弃解析它,因为 &lt;device&gt; 标记在它甚至可以到达那部分之前永远不会接近的代码。而且,如果你解决了这个问题,因为&lt;deviceset&gt; 是实际的根音,root.find('deviceset') 将返回None。而且,如果你解决了这个问题,你会在 .** 上得到一个语法错误。
  • @abarnert 哦,对不起,忽略我的导入——我正在改变事情,实际上是指xml.etree import ElementTree as ET

标签: python xpath elementtree


【解决方案1】:

我实际上不知道问题出在哪里,因为您没有向我们展示您的实际数据和代码,而且您向我们展示的内容甚至无法解决问题。

但我认为这是您的 XPath 查询中的额外空格。 @pin = "FB"@pin="FB" 不一样,不能匹配任何东西。

同时……

在 Python 中显式转义引号通常没有充分的理由。如果要在字符串中使用双引号,只需将字符串括在单引号中,反之亦然。如果两者都需要,答案通常是三倍(单引号或双引号)。

同时,我能做的只是猜测,您没有提供有效的 XML 或有效的代码来证明问题。

  • 没有xml.etree.parse这样的功能。有一个xml.etree.ElementTree.parse,这可能就是你想要的。
  • 随意缩进行意味着您会在任何东西运行之前得到IndentationError
  • 您的代码不完整 - 它依赖于您从未设置过的 __location__,并且您从未导入过导入。
  • 您在代码中间有一个杂散的**,它将引发SyntaxError
  • XML 中的 device 节点永远不会关闭,因此 ET 无法解析文件。
  • deviceset 节点是根节点,所以root.find('deviceset') 将返回None

此外,如果您尝试调试 95 个字符长的代码行,您真的应该将其分解以找出哪个部分正在中断,并让您有机会设置断点或将输入记录到部分不起作用。

解决所有这些问题后,唯一剩下的问题就是您的 xpath 不正确,因此我假设您的真实代码和数据也是如此,但无法确定。

无论如何,这是固定的 XML:

<deviceset>
<devices>
<device name="">
<connects>
<connect gate="G$1" pin="+15V_DC" pad="7"/>
<connect gate="G$1" pin="FB" pad="3"/>
<connect gate="G$1" pin="ICOM" pad="4"/>
<connect gate="G$1" pin="IN+" pad="5"/>
<connect gate="G$1" pin="IN-" pad="6"/>
<connect gate="G$1" pin="OUT_HI" pad="1"/>
<connect gate="G$1" pin="OUT_LO" pad="9"/>
<connect gate="G$1" pin="PWRCOM" pad="2"/>
</connects></device>
</devices>
</deviceset>'''

…和代码:

import os.path
from xml.etree import ElementTree as ET

file = open('foo.xml')
tree = ET.parse(file)
root = tree.getroot()
deviceset = root
connects = deviceset.find('devices').find('device').find('connects')
# Here we could print out stuff about connects to find out what's wrong.
nodes = connects.findall("./connect[@pin='FB']")
print(nodes[0].get('gate'))

运行时会打印:

G$1

【讨论】:

  • 谢谢,但我仍然在nodes = connects.findall("./connect[@pin = 'FB']") 行收到错误...。connects 打印出来非常好。
  • 抱歉,为了简洁起见,我粘贴了 sn-ps 并在此过程中犯了一些错误。当我将导致问题的区域加粗时,SO 就出现了** 语法。
  • @user1328021:张贴 sn-ps 很好,但不要在编辑时随意编造它们。这使得无法判断哪个问题是您的实际问题,以及哪些问题是在此过程中出现的新错误。创建一个SSCCE 并在本地运行它以确保它演示了您的问题,然后在此处发布。 (另外,不要尝试对代码应用格式;它会破坏代码。)
  • @user1328021:至于你的新问题……把空格去掉。
  • 谢谢!这从一开始就是我的问题——空格。感谢您的帮助,下次将创建一个 SSCCE。
猜你喜欢
  • 1970-01-01
  • 2022-08-22
  • 2016-07-26
  • 1970-01-01
  • 2017-10-12
  • 1970-01-01
  • 2016-02-23
  • 2018-11-06
  • 1970-01-01
相关资源
最近更新 更多