2016-05-04 8 views
2

Ich kann Werte aus Elementen extrahieren (mit lxml in Python 2.7), wenn ein Namespace verwendet wird. Ich kann jedoch nicht herausfinden, wie man Werte extrahiert, wenn ein zweiter Namespace verwendet wird. Ich möchte den Wert innerhalb //cc-cpl:MainClosedCaption/Id extrahieren, aber ich bekomme lxml.etree.XPathEvalError: Invalid expression Fehler. Um genau zu sein, ist der Wert Ich versuche, aus meiner Probe xml Exract ist urn:uuid:6ca58b51-9116-4131-8652-feaed20dca0dWert aus Element extrahieren, wenn zweiter Namespace in Lxml verwendet wird

a Hier ist der XML-snipped (von Digital Cinema Package):

<?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> 

Hier ein Beispiel-Code ist das funktioniert:

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 

Wenn ich versuche stattdessen die folgende XPath angeben: //ns:MainClosedCaption/ns:Id - ich mit Fehlern enden.

Wenn ich den Namespace angeben mit: pkl_namespace = 'http://www.digicine.com/PROTO-ASDCP-CC-CPL-20070926#"'

Ich erhalte ein lxml.etree.XPathEvalError: Invalid expression Fehler

Ich weiß, das ein dummer Versuch, aber die die gleichen Fehler erzeugen folgenden: '//ns:cc-cpl:MainClosed Caption/ns:cc-cpl:Id'

Ich habe versucht, Um die zwei Namespaces in ein Wörterbuch wie in dieser Antwort aufzunehmen: https://stackoverflow.com/a/36227869/2188572, und während ich keine Fehler erhalte, habe ich keine extrahierten Werte. Hier ist mein Wörterbuch:

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

und mein Kommando:

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

ich das gefunden, Extracting nested namespace from a xml using lxml die eigentlich genau die gleiche Art von XML ist, dass ich arbeite, aber sein Wunsch war zu bekommen die Namespace-URL, nicht die tatsächlichen Werte von Elementen.

Edit: die Methode aus der vorherige Antwort Mit dem Namensraum zu extrahieren, habe ich versucht, den folgenden, bekam aber die gleichen Fehler:

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 

und hier ist der Fehler in voller Länge:

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 

Antwort

2

Das Element Id in MainClosedCaption gehört zum Namespace 2004. Nur ein Attribut kann den Standardnamespace ändern. Attribute des Formulars xmlns:something="..." fügen nur einen Namespace hinzu, der explizit deklariert werden muss.

starten:

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

Erfolg !! Ich danke dir sehr. Ich glaube, ich war mit meinem ns1/ns2-Versuch in etwa auf dem richtigen Weg, aber meine allgemeine Verwirrung und mein Mangel an Wissen haben mich in die Irre geführt. –

+1

Ja, ich glaube, du warst sehr nah dran. Um Verwechslungen im Namensraum zu vermeiden, würde ich empfehlen, nützliche Etiketten zu verwenden (ich weiß nicht, ob Proto der beste ist). Namespaces namens 'ns1' bis' ns999' sind für Maschinen - aber sie mögen ihre Variablen 'var1' zu' var999' benennen. – phihag

+0

Sie haben Recht. Ich habe wahrscheinlich das 'ns:' in einem Stack-Überlauf-Beispiel gesehen und bin einfach dabei geblieben. –