在一些代码中,我使用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")
是的,这绝对比原版更干净,但我正在寻找一个可以将这些信息发给我的图书馆。
答案 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>
祝你好运