Python XML XPath部分失败消息

时间:2013-05-14 11:22:27

标签: python xml xpath

在一些代码中,我使用minidom库维护XML解析。

对于类似于以下的XML结构:

<a val="a1">
  <b val="b1">
    <c val="c1">
      Data
    </c>
  </b>
</a>

代码如下:

for a in doc.getElementsByTagName("a"):
    aId = a.getAttribute("val").encode('ascii')
    if aId == aExpected:
        aFound = a
        break
else: # not found
    raise Exception("No A '%s' found" % aExpected)
for b in aFound.getElementsByTagName("b"):
    bId = b.getAttribute("val").encode('ascii')
    if bId == bExpected:
        bFound = b
        break
else: # not found
    raise Exception("No B '%s' found" % bExpected)
# similar for c

我想使用XPath来查找数据。 我可以用(ElementTree)来做到这一点:

root.findall(".//a[@val=%s]/b[@val=%s]/c[@val=%s]" % (aExpected, bExpected, cExpected))

现在代码看起来好多了。 但是,当在XML中找不到数据时,findall()返回None,我必须手动分析第一个不匹配元素的文件。

ElementTree(或其他XML API)是否有可能同时使用XPath并让XPath返回第一个匹配失败点(类似于原始代码中的else子句)?

正如一个答案所指出的,代码可以替换为:

aFound = root.find(".//a[@val=%r]" % (aExpected,))
if not aFound:
    raise("A not present")
bFound = aFound.find("b[@val=%r]" % (bExpected,))
if not bFound:
    raise("B not present")
cFound = bFound.find("c[@val=%r]" % (cExpected,))
if not cFound:
    raise("C not present")

是的,这绝对比原版更干净,但我正在寻找一个可以将这些信息发给我的图书馆。

2 个答案:

答案 0 :(得分:0)

aFound = root.findall(".//a[@val=%r]" % (aExpected,))[0]
bFound = aFound.findall("b[@val=%r]" % (bExpected,))[0]
cFound = bFound.findall("c[@val=%r]" % (cExpected,))[0]

将在没有找到元素的第一行上引发IndexError。


或者,为避免在只需要所有元素时找到所有元素,请使用find

aFound = root.find(".//a[@val=%r]" % (aExpected,))
bFound = aFound.find("b[@val=%r]" % (bExpected,))
cFound = bFound.find("c[@val=%r]" % (cExpected,))

现在,{<1}}(因为AttributeError没有NoneType方法)将在之后的行上提出,而是没有找到Element的那个。

答案 1 :(得分:0)

用于跟随xml

    <a val="a1">
  <b val="b1">
    <c val="c1">
      Data
    </c>
  </b>
</a>

使用此代码

import xml.etree.ElementTree as ET

file = "sample.xml"
aExpected = "a1"
bExpected = "b1"
cExpected = "c1"

tree = ET.parse(file)
root = tree.getroot()

bFound = root.find("./b[@val='" + bExpected + "']")
cFound = root.find(".//c[@val='" + cExpected + "']")

print(root)
print(bFound)
print(cFound)

输出是:

<Element 'a' at 0x02919B10>
<Element 'b' at 0x02919BD0>
<Element 'c' at 0x02919C30>

xml.etree.ElementTree在XPath中找不到任何东西因为是根元素

如果要查找a元素,请按以下方式修改xml

  <root>
<a val="a1">
  <b val="b1">
    <c val="c1">
      Data
    </c>
  </b>
</a>
</root>

和代码

 import xml.etree.ElementTree as ET

file = "sample.xml"
aExpected = "a1"
bExpected = "b1"
cExpected = "c1"

tree = ET.parse(file)
root = tree.getroot()

aFound = root.find("./a[@val='" + aExpected + "']")
bFound = root.find(".//b[@val='" + bExpected + "']")
cFound = root.find(".//c[@val='" + cExpected + "']")

print(aFound)
print(bFound)
print(cFound)

结果将是

<Element 'a' at 0x02919B10>
<Element 'b' at 0x02919BD0>
<Element 'c' at 0x02919C30>

祝你好运