2013-05-14 49 views
0

在一些代碼中我維護那裏是使用minidom庫進行XML解析。Python XML XPath部分失敗消息

對於類似下面的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
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,)) 

現在的AttributeError(因爲NoneType沒有find法)將上線後引發找不到元素的人。

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任何becouse一個是根元素

如果你想找到一個元素修改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> 

致以問候