2016-05-04 27 views
2

1つの名前空間が使用されている場合、要素から値を抽出できます(Python 2.7ではlxmlを使用できます)。しかし、私は2番目の名前空間が使用されているときに値を抽出する方法を理解できません。私は//cc-cpl:MainClosedCaption/Idの中の値を抽出したいが、私はlxml.etree.XPathEvalError: Invalid expressionエラーが発生し続ける。 は、具体的には、私は私のサンプルXMLからexractしようとしている値は、ここでurn:uuid:6ca58b51-9116-4131-8652-feaed20dca0d2番目の名前空間がlxmlで使用されている場合の要素からの値の抽出

(デジタルシネマパッケージから)XMLを切り取られますです:ここでは

<?xml version="1.0" encoding="UTF-8"?> 
<CompositionPlaylist xmlns="http://www.digicine.com/PROTO-ASDCP-CPL-20040511#"> 
    <Reel> 
     <Id>urn:uuid:58cf368f-ed30-40d8-9258-dd7572035b69</Id> 
     <MainPicture> 
      <Id>urn:uuid:afe91f7a-6451-4b9f-be2e-345f9a28da6d</Id> 
     </MainPicture> 
     <cc-cpl:MainClosedCaption xmlns:cc-cpl="http://www.digicine.com/PROTO-ASDCP-CC-CPL-20070926#"> 
      <Id>urn:uuid:6ca58b51-9116-4131-8652-feaed20dca0d</Id> 
     </cc-cpl:MainClosedCaption> 
    </Reel> 
</CompositionPlaylist> 

はコードの例です。それは動作します:

from lxml import etree 
cpl_parse = etree.parse('filename.xml') 
pkl_namespace = cpl_parse.xpath('namespace-uri(.)') 
xmluuid = cpl_parse.xpath('//ns:MainPicture/ns:Id',namespaces={'ns': pkl_namespace}) 
for i in xmluuid: 
    print i.text 

私が代わりに次のXPathを指定しようとすると://ns:MainClosedCaption/ns:Id - 私はエラーで終わります。私は名前空間を指定

:私が試した '//ns:cc-cpl:MainClosed Caption/ns:cc-cpl:Id'

pkl_namespace = 'http://www.digicine.com/PROTO-ASDCP-CC-CPL-20070926#"'

私は、これは愚かな試みですけど、以下は同じエラーを生成lxml.etree.XPathEvalError: Invalid expressionエラーに

を受け取りますこの答えのように辞書に2つの名前空間を含めるには:https://stackoverflow.com/a/36227869/2188572、私はエラーは出ませんが、値は抽出されません。ここ は私の辞書です:

namespaces = { 
    'ns': 'http://www.digicine.com/PROTO-ASDCP-CPL-20040511#', 
    'ns2': 'http://www.digicine.com/PROTO-ASDCP-CC-CPL-20070926#', 
} 

と私のコマンド:

xmluuid = cpl_parse.xpath('//ns:AssetList/ns2:MainClosedCaption/ns2:Id',namespaces=namespaces) 

は、私は実際に私が働いているXMLの正確な同じ種類であるExtracting nested namespace from a xml using lxml、これを見つけましたが、彼の要求は、取得することでした名前空間のURLであり、要素の実際の値ではありません。

編集: 名前空間を抽出するために、前の回答からメソッドを使用して、私は次のことを試してみましたが、同じエラーを得た:

from lxml import etree 
import sys 
filename = sys.argv[1] 

cpl_parse = etree.parse(filename) 
pkl_namespace = etree.QName(cpl_parse.find('.//{*}MainClosedCaption')).namespace 
print pkl_namespace 
xmluuid = cpl_parse.xpath('//ns:cc-cpl:MainClosedCaption/ns:cc-cpl:Id',namespaces={'ns': pkl_namespace}) 
for i in xmluuid: 
    print i.text 

、ここでは、フルのエラーです:

Traceback (most recent call last): 
    File "sub.py", line 8, in <module> 
    xmluuid = cpl_parse.xpath('//ns:cc-cpl:MainClosedCaption/ns:cc-cpl:Id',namespaces={'ns': pkl_namespace}) 
    File "lxml.etree.pyx", line 2115, in lxml.etree._ElementTree.xpath (src/lxml/lxml.etree.c:57654) 
    File "xpath.pxi", line 370, in lxml.etree.XPathDocumentEvaluator.__call__ (src/lxml/lxml.etree.c:146564) 
    File "xpath.pxi", line 238, in lxml.etree._XPathEvaluatorBase._handle_result (src/lxml/lxml.etree.c:144962) 
    File "xpath.pxi", line 224, in lxml.etree._XPathEvaluatorBase._raise_eval_error (src/lxml/lxml.etree.c:144817) 
lxml.etree.XPathEvalError: Invalid expression 

答えて

2

MainClosedCaptionのId要素は2004年の名前空間に属します。属性xmlns="..."だけがデフォルト名前空間を変更できます。 xmlns:something="..."という形式の属性は、明示的に宣言しなければならない名前空間のみを追加します。

はこれを試してみてください:

from lxml import etree 
cpl_parse = etree.parse('filename.xml') 
xmluuid = cpl_parse.xpath('//proto2007:MainClosedCaption/proto2004:Id', namespaces={ 
    'proto2004': 'http://www.digicine.com/PROTO-ASDCP-CPL-20040511#', 
    'proto2007': 'http://www.digicine.com/PROTO-ASDCP-CC-CPL-20070926#', 
}) 
for i in xmluuid: 
    print(i.text) 
+0

成功!!どうもありがとうございます。私はns1/ns2の試行で大まかに正しいと思ったが、私の一般的な混乱と知識の欠如は私を迷わせた。 –

+1

はい私はあなたが非常に近いと信じています。名前空間の混乱を避けるために、便利なラベルを使用することをお勧めします(protoが最適かどうかわかりません)。 'ns1'から' ns999'という名前空間はマシンのためのものですが、それらの変数を 'var1'から' var999'にするのが好きです。 – phihag

+0

あなたは正しいです。おそらくスタックオーバーフローの例で 'ns:'を見ただけでスタックしてしまいました。 –

関連する問題