2016-07-11 5 views
0

Ich habe diese XPath:

/document/offers/offer/concat(price/text(), for $r in . return 'default-value'[not($r/price/text())]) 

, die (für fehlende Tags Standardwert) für dieses Dokument mein Problem löst:

<document> 
    <company> 
    <ceo>Elon Musk</ceo> 
    <employees>13058</employees> 
    <address> 
     <city>Palo Alto</city> 
     <state>California</state> 
     <country>USA</country> 
    </address> 
    </company> 
    <offers> 
    <offer avail="0"> 
     <id>1</id> 
     <model>Tesla Roadster</model> 
     <imageUrl>https://www.teslamotors.com/sites/default/files/styles/blog-picture_2x_1400xvar_/public/0H8E6227_1.jpg</imageUrl> 
    </offer> 
    <offer avail="1"> 
     <id>2</id> 
     <model>Tesla Model S</model> 
     <price>63400.00</price> 
     <offerUrl>https://www.teslamotors.com/models</offerUrl> 
     <imageUrl>https://www.teslamotors.com/tesla_theme/assets/img/models/section-initial.jpg</imageUrl> 
    </offer> 
    <offer avail="1"> 
     <id>3</id> 
     <model>Tesla Model X</model> 
     <price>69300.00</price> 
     <offerUrl>https://www.teslamotors.com/modelx</offerUrl> 
     <imageUrl>https://www.teslamotors.com/tesla_theme/assets/img/modelx/section-exterior-profile.jpg</imageUrl> 
    </offer> 
    <offer avail="1"> 
     <id>4</id> 
     <model>Tesla Model 3</model> 
     <price>35000.00</price> 
     <offerUrl>https://www.teslamotors.com/model3</offerUrl> 
     <imageUrl>https://www.teslamotors.com/sites/default/files/images/model-3/gallery/gallery-1.jpg</imageUrl> 
    </offer> 
    </offers> 
</document> 

durch Rückkehr:

default-value 
63400.00 
69300.00 
35000.00 

Nach http://videlibri.sourceforge.net/cgi-bin/xidelcgi, das funktioniert, aber ich kann nicht mit lxml in Python arbeiten. Im Moment weiß ich nicht einmal, wie man diese Art von xpath googlen soll. Also ... wie diese "inneren Fors" in XPaths heißen?

+1

lxml verwendet libxml, die XPath implementiert nur 1,0, also hier das Problem. –

Antwort

3

Das ist ein xpath2 for-expressions, der nicht von Lxml oder XML.etree in Python unterstützt wird. Man könnte es für

-Schleife ein replizieren
from lxml import etree 

xml = etree.parse("the_file") 
for node in xml.xpath("//document/offers/offer"): 
    pr = node.xpath("./price") 
    print(pr[0].text if pr else "Default-value") 

Welche würden Sie geben:

Default-value 
63400.00 
69300.00 
35000.00 
+0

der ganze Sinn war, 'n + 1' Abfragen für' n' Knoten zu vermeiden, was so langsam ist :(Aber danke. – noisy

+1

@noisy, ... die zweite Abfrage sucht nur einen Teilbaum. Das ist waayay schneller als das gesamte Dokument, und, nun, das * hat * Ihre Frage beantwortet. Wenn Sie wirklich wissen wollten, wie Sie dies in XPath 1.0 auf eine performante Art und Weise tun können, sollten Sie das stattdessen gefragt haben. –

+0

@CharlesDuffy: korrekt. Antwort ist bereits akzeptiert. Ich muss einige Tests machen. Ich habe mehr als 500 000 Knoten, also selbst wenn diese Unterabfragen viel schneller sind, müssen sie 500 000 von ihnen sein, anstatt eins. – noisy

Verwandte Themen