Python “的名字是什么?”;以$x的价格。。。返回……”;XPath中的语法?

Python “的名字是什么?”;以$x的价格。。。返回……”;XPath中的语法?,python,xml,xpath,lxml,Python,Xml,Xpath,Lxml,我有一个xpath: /document/offers/offer/concat(price/text(), for $r in . return 'default-value'[not($r/price/text())]) 这解决了此文档的问题(缺少标记的默认值): <document> <company> <ceo>Elon Musk</ceo> <employees>13058</employees&g

我有一个xpath:

/document/offers/offer/concat(price/text(), for $r in . return 'default-value'[not($r/price/text())])
这解决了此文档的问题(缺少标记的默认值):

<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>
根据,这是可行的,但我无法在python中使用lxml实现这一点。现在我甚至不知道如何用谷歌搜索这种类型的xpath。所以这些“内部FOR”在XPath中是如何调用的?

这是python中lxml或xml.etree不支持的。您可以使用for循环复制它

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")
这将给你:

Default-value
63400.00
69300.00
35000.00
这是python中lxml或xml.etree不支持的。您可以使用for循环复制它

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")
这将给你:

Default-value
63400.00
69300.00
35000.00

lxml使用libxml,它只实现XPath 1.0,因此这里是您的问题。lxml使用libxml,它只实现XPath 1.0,因此这里是您的问题。这一点的全部目的是避免对
n+1
节点进行
n
查询,这太慢了:(但谢谢。@Noised,…第二个查询只是搜索一个子树。这比整个文档要快。而且,这确实回答了你的问题。如果你真正想知道的是如何在XPath 1.0中以一种高效的方式完成这项工作,你应该问这个问题。@CharlesDuffy:正确。答案已经被接受。我需要做some测试。我有50多万个节点,所以即使这些子查询速度快得多,它们也必须是50万个,而不是一个。当然。如果性能是你的第一个目标,那么Python和XPath可能不是用于这项工作的合适堆栈。我看到一些人通过组合clojure.data.xml/pars报告了令人印象深刻的性能数字e和specter——但即使不走那么远,任何像样的XQuery数据存储都会为您提供单次调用语法和适当的查询优化器和数据库索引。顺便问一句,如果您关心性能,您为什么要使用
//price
而不是
/price
?当搜索不需要时,进行递归搜索没有意义不需要。(顺便说一句,这是一个好的XQuery优化器可以解决的问题之一——检查结构索引可以验证
price
仅直接位于
offer
之下,因此它不需要递归)。对于
//document
,同样如此,除非您在\u文件中实际有多个文档,但即使如此,给出一个直接路径也比执行无限递归搜索更有效。这一点的全部目的是避免对
n
节点进行
n+1
查询,这非常缓慢:(但谢谢。@Noised,…第二个查询只是搜索一个子树。这比整个文档要快。而且,这确实回答了你的问题。如果你真正想知道的是如何在XPath 1.0中以一种高效的方式完成这项工作,你应该问这个问题。@CharlesDuffy:正确。答案已经被接受。我需要做some测试。我有50多万个节点,所以即使这些子查询速度快得多,它们也必须是50万个,而不是一个。当然。如果性能是你的第一个目标,那么Python和XPath可能不是用于这项工作的合适堆栈。我看到一些人通过组合clojure.data.xml/pars报告了令人印象深刻的性能数字e和specter——但即使不走那么远,任何像样的XQuery数据存储都会为您提供单次调用语法和适当的查询优化器和数据库索引。顺便问一句,如果您关心性能,您为什么要使用
//price
而不是
/price
?当搜索不需要时,进行递归搜索没有意义不需要。(顺便说一句,这是一个好的XQuery优化器可以解决的问题之一——检查结构索引可以验证
price
仅直接位于
offer
之下,因此它不需要递归)。对于
//document
,同样如此,除非您在\u文件
中实际有多个文档,但即使如此,给出直接路径也比执行无限递归搜索更有效。