具有两个条件的lxml XPath搜索

问题描述

我的XML文件是:

<releases>
    <release id="1">
        <title>Title1</title>
        <formats>
            <format name="CD" qty="2" text="">
            </format>
        </formats>
        <released>2016-02-00</released>
    </release>
    <release id="2">
        <title>Title2</title>
        <formats>
            <format name="LP" qty="2" text="">
            </format>
        </formats>
        <released>2018-03-00</released>
    </release>
    <release id="3">
        <title>Title3</title>
        <formats>
            <format name="CD" qty="1" text="">
            </format>
        </formats>
        <released>1995-01-15</released>
    </release>  
</releases>

在Python3中,我想找到版本ID,其中“格式”名称=“ CD”,“已发布”文本包含文本“ 1995”(因此应为版本ID 3)

我有这段代码可以找到CD发行版,并打印发行日期:

for rls in root.findall(".//format[@name='CD']....//released"):
    print (rls.tag,rls.attrib,rls.text)

我也有这段代码,可以找到所有带有“ 1995”的版本,并打印出第一个结果的日期:

print (root.xpath("/releases/release/released[contains(text(),'1995')]")[0].text)

我在查找如何将两者结合时遇到了麻烦(而且我在一个中使用findall,而在另一个中使用xpath,这并不美观)。

解决方法

您可以在XPath中的选择器的谓词部分中组合条件。下面告诉XPath:

  • 返回所有release个节点,这些节点包含:
    • 具有format
    • 属性的name=CD节点
    • 一个released节点,文本中包含1995
xml.xpath("./release[.//format[@name='CD'] and .//released[contains(text(),'1995')]]/@id")
# returns:
['3']
,

此XPath,

/releases/release[formats/format/@name='CD'][starts-with(released,'1995')]

将选择release日期以CD开头的released格式的1995个元素,

<release id="3">
    <title>Title3</title>
    <formats>
        <format name="CD" qty="1" text="">
        </format>
    </formats>
    <released>1995-01-15</released>
</release>  

根据要求。

您提到需要id属性。如果您确实想遍历所有此类id属性而不是元素本身,则只需将/@id附加到上述XPath中即可。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...