2017-06-16 3 views
1

Ich entschuldige mich, wenn diese Frage einfach durch Suchen und Lesen der LXML-Dokumentation beantwortet werden konnte, aber ich habe versucht, vergeblich.LXML mit XPath und ETXPath in Python

Ich habe lxml's findall ziemlich häufig verwendet, um eine XML-Datei abzufragen. Vor kurzem musste ich Wildcards verwenden, um die Daten zu extrahieren, die ich brauche. Dies hat mich dazu gebracht, Xpath zu benutzen.

Ich habe es geschafft, das funktioniert mit ETXPath aber nicht Xpath. Ich bin verwirrt warum. Ein Auszug aus der XML-Datei, die

findshiz = ETXPath("//" + namespace + "DC/" + namespace + "Overviews/" + namespace + "OverviewLevelTimeStamp[" + namespace + "Identifier= 'Z 1 Index, TRADE']") 
required_nodes = findshiz(gap_xml) 

zu extrahieren

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<DC xmlns="http://tradefinder.db.com/Schemas/MEL/MelHorizon_0_4_2.xsd"> 
<Header> 
    <FileName>DBL_MPA_Gap_PRD_2017-06-01T07-50-52.xml</FileName> 
    <ValidityDate>2017-05-31</ValidityDate> 
    <Version>0.42</Version> 
    <NoOfRecords>17228</NoOfRecords> 
</Header> 
<Overviews> 
<OverviewLevelTimeStamp> 
     <Identifier>Z 1 Index, TRADE</Identifier> 
     <Level>2.2120000000000002</Level> 
     <Timestamp>09:00:00.000</Timestamp> 
</OverviewLevelTimeStamp> 
</Overviews> 
</DC> 

Und mein Python-Code verwendet, wo "gap_xml" die Analyse der Datei =.

Dieser Code funktioniert. Aus irgendeinem Grund, wenn ich versuche, Xpath zu verwenden, tut es das nicht. Dazu muss ich nur ETXPath mit xpath umbenennen. Der Grund dafür ist, dass ich Wildcards verwenden muss, also statt "Z 1 Index, TRADE" wäre es Z 1 Index *.

Danke und lassen Sie mich sowieso die Frage zu verbessern.

+0

Was ist * Namensraum *? Bitte zeigen Sie die Zuweisungszeile: 'namespace = ...' – Parfait

Antwort

1

contains(., "Z 1 Index,") ist wie sagen *Z1 Index*, die eine substring Suche ist. Hier

ist ein Beispiel für contains verwendet, die wie ein Wildcard von XPath ist und Karte den Namespace verwendet:

 : import lxml.etree as etree 

     : xstring = """ 
    ...: <DC xmlns="http://tradefinder.db.com/Schemas/MEL/MelHorizon_0_4_2.xsd"> 
    ...: <Header> 
    ...:  <FileName>DBL_MPA_Gap_PRD_2017-06-01T07-50-52.xml</FileName> 
    ...:  <ValidityDate>2017-05-31</ValidityDate> 
    ...:  <Version>0.42</Version> 
    ...:  <NoOfRecords>17228</NoOfRecords> 
    ...: </Header> 
    ...: <Overviews> 
    ...: <OverviewLevelTimeStamp> 
    ...:   <Identifier>Z 1 Index, TRADE</Identifier> 
    ...:   <Level>2.2120000000000002</Level> 
    ...:   <Timestamp>09:00:00.000</Timestamp> 
    ...: </OverviewLevelTimeStamp> 
    ...: </Overviews> 
    ...: </DC>""" 

xstring = etree.fromstring(xstring) 

nsmap = {'ns': 'http://tradefinder.db.com/Schemas/MEL/MelHorizon_0_4_2.xsd'} 

print xstring.xpath('//ns:OverviewLevelTimeStamp[ns:Identifier[contains(., "Z 1 Index,")]]', namespaces=nsmap) 

Ergebnisse in

[<Element {http://tradefinder.db.com/Schemas/MEL/MelHorizon_0_4_2.xsd}OverviewLevelTimeStamp at 0x10647aa70>] 

Beachten Sie, dass lxml XPath eine Liste zurückgibt , so müssen Sie den übereinstimmenden Knoten aus der Liste extrahieren.

+0

Hallo Sal, danke für deine Antwort. Ich kann allerdings nicht 'contains' verwenden, da ich zwischen zwei String-Suchen einen Platzhalter benötige. Außerdem kann ich hier 'tostring' nicht verwenden, da die Datei ein sehr großes xml ist. – naiminp

+0

@naiminp 'tostring' war nur für mein Beispiel, ich sage dir nicht, es zu benutzen. "Contains" ist ein Platzhalter, der eine Bearbeitung vorbereitet. . – salparadise