【问题标题】:XPath to select by exact matches of children nodesXPath 通过子节点的精确匹配来选择
【发布时间】:2016-06-23 16:29:17
【问题描述】:

示例 XML:

<cacheFile>
    <workflows>
        <workflow wfid="999" name="John" >
            <attached docid="001" />
            <attached docid="002" />
        </workflow>
        <workflow wfid="888" name="John" >
            <attached docid="001" />
            <attached docid="002" />
            <attached docid="003" />
        </workflow>
    </workflows>
    <otherData/>
</cacheFile>

正如上面的 sn-p 所示,我有一个 XML 文件,其中包含有关各种工作流项的数据;每个工作流元素都包含自己的 ID、分配的工作人员的名称和附加的文档 ID 列表。仅使用名称属性和文档 ID 列表,我需要选择正确的工作流 ID。

我想出了以下 XPath 查询,它几乎可以按预期工作:

//cache/workflows/workflow[@name='John' and ./document[@id='001'] and ./document[@id='002']]"

问题是,这个查询返回两个工作流项;我需要它只返回完全匹配(wfid=999)。有几十种方法可以手动整理结果,但我认为必须有一些我无法找到的 XPath 函数可能会限制查询执行期间的结果。也许是限制子元素数量的约束?

【问题讨论】:

  • 你不能使用wifid?
  • 没有“document”标签,是“attached”。

标签: xml xpath


【解决方案1】:

你可以数attached docid属性:

x = """<cacheFile>
    <workflows>
        <workflow wfid="999" name="John" >
            <attached docid="001" />
            <attached docid="002" />
        </workflow>
        <workflow wfid="888" name="John" >
            <attached docid="001" />
            <attached docid="002" />
            <attached docid="003" />
        </workflow>
    </workflows>
    <otherData/>
</cacheFile>"""

import lxml.etree as et

xml = et.fromstring(x)


print(xml.xpath("//workflows/workflow[count(./attached/@docid) < 3]"))

或者只计算附件就足够了:

"//workflows/workflow[count(./attached) < 3]"

您可以使用 doc 值并确保只有 2 个:

xpath("//workflows/workflow[./attached[3]='' and ./attached[1]/@docid=001 and ./attached[2]/@docid=002]")

当然如果你可以只使用wifid,那就简单多了:

print(xml.xpath('//workflows/workflow[@wfid="999"]'))

【讨论】:

  • count() 函数成功了,我知道我遗漏了一些简单的东西……谢谢!
  • 没有问题,不客气,有很多不同的方法可以做到这一点,这实际上取决于限制条件。
猜你喜欢
  • 1970-01-01
  • 2018-03-15
  • 2010-12-01
  • 1970-01-01
  • 2015-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-09
相关资源
最近更新 更多