如何使用XPath选取仅包含Sex为boy的Child子节点的Children节点
问题解答
结论先行
纯标准XPath(1.0/2.0版本,也是目前绝大多数工具支持的版本)无法直接实现你的需求,原因是XPath是节点查询语言,仅能选择文档中已存在的节点,不能修改节点结构或生成新的节点。
为什么你尝试的两条语句不符合要求
//Children/Child[Sex='boy']:作用是匹配所有Sex值为boy的Child节点,返回的是多个独立的Child节点集合,自然不会携带外层的Children包裹。//Children[Child/Sex='boy']:作用是匹配「至少存在一个Sex值为boy的Child子节点」的Children节点,返回的是文档中原有的Children节点,该节点本身就包含所有子节点,不会自动过滤不符合要求的Child。
可行实现方案
你需要的结果属于XML结构转换范畴,可以通过XPath配合宿主语言或XSLT实现,以下是两种常用方案:
方案1:使用XSLT转换
你可以通过以下简单的XSLT模板完成转换,直接输出你需要的结构:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 匹配原Children节点,构造新的同名节点 --> <xsl:template match="/Parent/Children"> <Children> <!-- 仅复制符合条件的Child节点 --> <xsl:copy-of select="Child[Sex='boy']"/> </Children> </xsl:template> <!-- 忽略其他不需要的节点 --> <xsl:template match="*"/> </xsl:stylesheet>
方案2:在代码中结合XPath实现
以Python的lxml库为例,操作逻辑如下:
from lxml import etree # 加载原始XML xml_content = """你的原始XML内容""" root = etree.fromstring(xml_content.encode()) # 用XPath筛选符合要求的Child节点 boy_childs = root.xpath("./Children/Child[Sex='boy']") # 手动构造新的Children节点包裹筛选结果 new_children = etree.Element("Children") for child in boy_childs: new_children.append(child) # 输出结果 print(etree.tostring(new_children, pretty_print=True, encoding="utf-8").decode())
内容的提问来源于stack exchange,提问作者Soren Werk
相关产品推荐
相关产品推荐

