2016-05-21 2 views
0

私はfield1field2を見つけようとしている。この例ではlxml:各検索語句にxmlns(localhost)パスを追加せずにフィールドを検索するにはどうすればよいですか?

... 
<soap:Body> 
<Request xmlns="http://localhost/"> 
<Test> 
<field1>hello</field1> 
<field2>world</field2> 
</Test> 
</Request> 
</soap:Body> 
... 

(3.6.0)lxmlのを使用してSOAP xmlファイル内のフィールドを見つけるためにしようとしています。

私はフィールドを検索し、検索語にパスを追加する必要があります。

print (myroot.find(".//{http://localhost/}field1").tag) # prints 'field1' 

それなしで、私は何も

print (myroot.find("field1").tag) # finds 'None' 

を見つけることができません検索する他の方法はありますフィールド情報を入力せずにフィールドタグ(ここではfield1)を入力しますか?

全例以下:

from lxml import etree 

example = """<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<soap:Body><Request xmlns="http://localhost/"> 
<Test><field1>hello</field1><field2>world</field2></Test> 
</Request></soap:Body></soap:Envelope> 
""" 
myroot = etree.fromstring(example) 

# this works 
print (myroot.find(".//{http://localhost/}field1").text) 
print (myroot.find(".//{http://localhost/}field2").text) 

# this fails 
print (myroot.find(".//field1").text) 
print (myroot.find("field1").text) 

コメント:SOAP要求の入力が与えられて、私は物事を簡単にするために、実際のライブでそれを変更することはできません。

答えて

1

XPathを使用して要素を選択するときに名前空間を無視する方法がありますが、それは良い方法ではありません。ネームスペースには理由があります。とにかく、そこたびに名前空間URIにマッピングされた名前空間接頭辞を使用して、代わりの実際の名前空間URIを使用することにより、すなわち、名前空間内の要素参照するためのクリーンな方法です:

..... 
>>> ns = {'d': 'http://localhost/'} 
>>> print (myroot.find(".//d:field1", ns).text) 
hello 
>>> print (myroot.find(".//d:field2", ns).text) 
world 
+0

これは少し進歩しては、まだ私を必要としコード内の 'http:// localhost /'を参照してください。名前空間が異なる場合にコードがフィールドを見つけることができるように、使用される名前空間の 'myroot'を照会する安全な方法はありますか? (現実世界では、.netサービスに送信されたリクエストがいっぱいで、すべてのリクエストに 'http:// localhost /'の参照が含まれているわけではないログを解析しています) – 576i

+0

問題は、 XMLはルート要素レベルで宣言されていないので、 'myroot'では直接利用できません。 'xmlns =" .. "'宣言された要素は常に 'Request'という名前になりますか? – har07

+0

まだ分かりません。私は異種の当事者が.netサービスを呼び出し、その呼び出し動作が一貫していません。私はルートレベルでxmlsnを宣言し、これをさらにフィールドで繰り返される名前にすることができます... ' hello' – 576i

関連する問題