具有两个条件的 lxml XPath 搜索

lxml XPath search with two conditions

我的 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 中,我想找到“格式”名称 =“CD”且“已发布”文本包含文本“1995”的版本 ID(因此版本 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 到:

  • return 所有 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')]

将 select release 格式 released 日期以 1995

开头的 CD 元素
<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。