Xpath 属性和元素上的xquery筛选器
我有以下简单的XML文档:Xpath 属性和元素上的xquery筛选器,xpath,xquery,Xpath,Xquery,我有以下简单的XML文档: <?xml version="1.0" encoding="UTF-8"?> <cars> <car> <data attrib="Make"> <text>Volvo</text> </data> <data attrib="Model"> <text>85
<?xml version="1.0" encoding="UTF-8"?>
<cars>
<car>
<data attrib="Make">
<text>Volvo</text>
</data>
<data attrib="Model">
<text>855</text>
</data>
</car>
<car>
<data attrib="Make">
<text>Volvo</text>
</data>
<data attrib="Model">
<text>745</text>
</data>
</car>
<car>
<data attrib="Make">
<text>Volvo</text>
</data>
<data attrib="Model">
<text>V70R</text>
</data>
</car>
</cars>
这将返回以下结果:
<data attrib="Model"><text>855</text></data>
855
我希望XPath返回匹配的整个
块
因此,返回数据如下所示:
<cars>
<car>
<data attrib="Make">
<text>Volvo</text>
</data>
<data attrib="Model">
<text>855</text>
</data>
</car>
</cars>
沃尔沃汽车
855
我如何修改上面的XPath表达式来实现这一点?XPath返回您所访问的任何节点-在您的示例中,您将返回到
数据,因此这就是您要返回的内容。如果您想要car
,请将谓词放在car
之后
/cars/car[data/@attrib='Model' and data/text='855']
或者,稍微短一点
/cars/car[data[@attrib='Model' and text='855']]
你可以随时运行它
XQuery生成所需的输出:
<cars>
{/cars/car[data[@attrib='Model' and text='855']]}
</cars>
{/cars/car[data[@attrib='Model'和text='855']]
这里有一个完整的、可能是最短的XSLT解决方案之一:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" />
<xsl:template match="/*">
<cars>
<xsl:copy-of select="car[data[@attrib='Model' and text='855']]"/>
</cars>
</xsl:template>
</xsl:stylesheet>
<cars>
<car>
<data attrib="Make">
<text>Volvo</text>
</data>
<data attrib="Model">
<text>855</text>
</data>
</car>
<car>
<data attrib="Make">
<text>Volvo</text>
</data>
<data attrib="Model">
<text>745</text>
</data>
</car>
<car>
<data attrib="Make">
<text>Volvo</text>
</data>
<data attrib="Model">
<text>V70R</text>
</data>
</car>
</cars>
<cars>
<car>
<data attrib="Make">
<text>Volvo</text>
</data>
<data attrib="Model">
<text>855</text>
</data>
</car>
</cars>
但是,使用众所周知的进行以下转换既易于编写,又提供了最大的灵活性、可扩展性和可维护性:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="car[not(data[@attrib='Model' and text='855'])]"/>
</xsl:stylesheet>
当对提供的XML文档应用这两种转换之一时:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" />
<xsl:template match="/*">
<cars>
<xsl:copy-of select="car[data[@attrib='Model' and text='855']]"/>
</cars>
</xsl:template>
</xsl:stylesheet>
<cars>
<car>
<data attrib="Make">
<text>Volvo</text>
</data>
<data attrib="Model">
<text>855</text>
</data>
</car>
<car>
<data attrib="Make">
<text>Volvo</text>
</data>
<data attrib="Model">
<text>745</text>
</data>
</car>
<car>
<data attrib="Make">
<text>Volvo</text>
</data>
<data attrib="Model">
<text>V70R</text>
</data>
</car>
</cars>
<cars>
<car>
<data attrib="Make">
<text>Volvo</text>
</data>
<data attrib="Model">
<text>855</text>
</data>
</car>
</cars>
沃尔沃汽车
855
沃尔沃汽车
745
沃尔沃汽车
V70R
生成所需的正确结果:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" />
<xsl:template match="/*">
<cars>
<xsl:copy-of select="car[data[@attrib='Model' and text='855']]"/>
</cars>
</xsl:template>
</xsl:stylesheet>
<cars>
<car>
<data attrib="Make">
<text>Volvo</text>
</data>
<data attrib="Model">
<text>855</text>
</data>
</car>
<car>
<data attrib="Make">
<text>Volvo</text>
</data>
<data attrib="Model">
<text>745</text>
</data>
</car>
<car>
<data attrib="Make">
<text>Volvo</text>
</data>
<data attrib="Model">
<text>V70R</text>
</data>
</car>
</cars>
<cars>
<car>
<data attrib="Make">
<text>Volvo</text>
</data>
<data attrib="Model">
<text>855</text>
</data>
</car>
</cars>
沃尔沃汽车
855
说明:
第一个转换生成顶部元素cars
,然后简单地选择想要的car
元素并将其复制为cars
的主体
第二种转换基于最基本、最强大的XSLT设计模式之一——使用并覆盖标识规则
标识模板按“原样”复制每个匹配的节点(为其选择要处理的节点)
有一个模板覆盖标识规则。此模板匹配任何汽车
,对于这些汽车,数据[@attrib='Model'和text='855']
不正确。模板的主体是空的,这导致匹配的car
元素没有复制到输出中——换句话说,我们可以说amy matchingcar
元素被“删除”
只需添加到这个响应中:这将返回所选的“car”元素。它不会按要求将其包装在“cars”元素中。由于输入不包含只有一个子元素的现有“cars”元素,因此只能通过构造新的“cars”元素来实现此输出,为此,需要使用XQuery而不是XPath,使用XSLT比使用XQuery更容易、更自然地进行此类处理。@DimitreNovatchev您能给出一个XSLT示例吗?