首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Python解析带有条件的ONIX xml

使用Python解析带有条件的ONIX xml
EN

Stack Overflow用户
提问于 2021-12-17 20:56:47
回答 1查看 117关注 0票数 0

我正在尝试使用Pythonlxml解析器从XML格式文件中提取一些信息。

除其他事项外,我在文件中感兴趣的部分如下:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<ProductSupply>
       <SupplyDetail>
          <Supplier>
             <SupplierRole>03</SupplierRole>
             <SupplierName>EGEN</SupplierName>
          </Supplier>
          <ProductAvailability>40</ProductAvailability>
          <Price>
             <PriceType>01</PriceType>
             <PriceAmount>0.00</PriceAmount>
             <Tax>
                <TaxType>01</TaxType>
                <TaxRateCode>Z</TaxRateCode>
                <TaxRatePercent>0</TaxRatePercent>
                <TaxableAmount>0.00</TaxableAmount>
                <TaxAmount>0.00</TaxAmount>
             </Tax>
             <CurrencyCode>NOK</CurrencyCode>
          </Price>
          <Price>
             <PriceType>02</PriceType>
             <PriceQualifier>05</PriceQualifier>
             <PriceAmount>0.00</PriceAmount>
             <Tax>
                <TaxType>01</TaxType>
                <TaxRateCode>Z</TaxRateCode>
                <TaxRatePercent>0</TaxRatePercent>
                <TaxableAmount>0.00</TaxableAmount>
                <TaxAmount>0.00</TaxAmount>
             </Tax>
             <CurrencyCode>NOK</CurrencyCode>
          </Price>
       </SupplyDetail>
    </ProductSupply>

我需要在以下条件下获得价格:

PriceType='02' and CurrencyCode='NOK' and PriceQualifier='05'

我试过:

代码语言:javascript
复制
price = p.find(
"ProductSupply/SupplyDetail[Supplier/SupplierRole='03']/Price[PriceType='02' \
and CurrencyCode='NOK' and PriceQualifier='05']/PriceAmount").text

由于某些原因,我的带有XPath运算符的and无法工作,并得到以下错误:

代码语言:javascript
复制
File "<string>", line unknown
    SyntaxError: invalid predicate

知道怎么接近它吗?任何帮助都是非常感谢的!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-18 10:18:16

TL;DR:使用xpath(),因为find*()方法不支持像and这样的布尔运算符。

作为丹尼尔建议,您应该对(相当复杂的) XPath表达式使用lxml的解析器方法xpath()

XPath

XPath表达式包含使用布尔算子 (XPath 1.0)的节点测试和https://en.wikipedia.org/wiki/XPath#Predicates

代码语言:javascript
复制
ProductSupply/SupplyDetail[Supplier/SupplierRole='03']/Price[PriceType='02' \
and CurrencyCode='NOK' and PriceQualifier='05']/PriceAmount

提示:在线测试(参见Xpather演示)。这表明它按照预期找到了单个元素<PriceAmount>0.00</PriceAmount>

使用find()方法

根据Python,您可以使用以下find方法接受匹配表达式(例如XPath)作为参数:

  1. find
  2. findAll

问题:有限的XPath语法支持find()

虽然他们的支持XPath语法是有限的!

这个限制包括与and一样的逻辑运算符。卡尔·桑顿( Karl )在他的XML解析: Python ~ XPath ~逻辑和Shiori页面上解释了这一点。

另一方面,文档更喜欢它们:

.find*() 方法通常比成熟的XPath支持更快的。它们还通过.iterfind()方法支持增量树处理,而XPath总是在返回结果之前收集所有结果。因此,由于速度和内存方面的原因,在不需要高度选择性的XPath查询时,建议使用它们而不是XPath。

(强调地雷)

使用lxml的xpath()

因此,让我们从更安全和更丰富的xpath()函数开始(在过早优化之前)。例如:

代码语言:javascript
复制
# the node predicates to apply within XPath
sd_predicate = "[Supplier/SupplierRole='03']"
p_predicate = "[PriceType='02' and CurrencyCode='NOK' and PriceQualifier='05']"

pa_xpath = f"ProductSupply/SupplyDetail{sd_predicate}/Price{p_predicate}/PriceAmount"  # building XPath including predicates with f-string
print("Using XPath:", pa_xpath) # remove after debugging

root = tree.getroot()
price_amount = root.xpath(pa_xpath)
print("XPath evaluated to:", price_amount) # remove after debugging

另请参阅:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70398822

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档