XSLT按属性查询节点
问题描述:
我需要查询一个大的XML文件,以提取仅包含具有等于给定参数的属性的所需节点的子XML树。XSLT按属性查询节点
这里是我的源文件
<a:level1 xmlns:a="some:a" xmlns:b="some:b"
xmlns:c="some:c" xmlns:d="some:d">
<a:level2>
<b:level3>
<b:date a:value="TODAY">
<c:level4>
<d:level5>
<d:level6 a:value="AAA">
<d:level7 a:value="AAA_AAA">
<d:level8 a:value="XXX/123">
<d:leaf a:value="150415">
<b:leaf1>100</b:leaf1>
<b:leaf2>100</b:leaf2>
</d:leaf>
<d:leaf a:value="200814">
<b:leaf1>1961</b:leaf1>
<b:leaf2>1961</b:leaf2>
</d:leaf>
</d:level8>
</d:level7>
</d:level6>
<d:level6 a:value="BBB">
<d:level7 a:value="BBB_BBB">
<d:level8 a:value="XXX/123">
<d:leaf a:value="1505">
<b:leaf1>0.42</b:leaf1>
<b:leaf2>0.42</b:leaf2>
</d:leaf>
</d:level8>
</d:level7>
</d:level6>
</d:level5>
</c:level4>
</b:date>
</b:level3>
</a:level2>
</a:level1>
,这里是我的样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:a="xmlCache">
<xsl:param name="myparam" as="xs:string" required="no"/>
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*">
<xsl:message><xsl:value-of select="@a:value"/></xsl:message>
<xsl:if test="@a:value=$myparam">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
但它似乎不工作。有人可以帮忙吗?
更新:对不清楚的问题抱歉。我想提取整个子集的XML树。例如,如果参数为AAA,则输出为:
<a:level1 xmlns:a="some:a" xmlns:b="some:b"
xmlns:c="some:c" xmlns:d="some:d">
<a:level2>
<b:level3>
<b:date a:value="TODAY">
<c:level4>
<d:level5>
<d:level6 a:value="AAA">
<d:level7 a:value="AAA_AAA">
<d:level8 a:value="XXX/123">
<d:leaf a:value="150415">
<b:leaf1>100</b:leaf1>
<b:leaf2>100</b:leaf2>
</d:leaf>
<d:leaf a:value="200814">
<b:leaf1>1961</b:leaf1>
<b:leaf2>1961</b:leaf2>
</d:leaf>
</d:level8>
</d:level7>
</d:level6>
</d:level5>
</c:level4>
</b:date>
</b:level3>
</a:level2>
</a:level1>
答
更多通过猜测类似以下内容的是您正在寻找的内容。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:a="xmlCache">
<xsl:param name="myparam"/>
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*" mode ="copy" >
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="copy"/>
</xsl:copy>
</xsl:template>
<xsl:template match ="node()|@*">
<xsl:choose>
<xsl:when test="@*[name()='a:value']=$myparam">
<xsl:copy>
<xsl:apply-templates select="@*|*" mode="copy"/>
</xsl:copy>
</xsl:when>
<xsl:when test="descendant::*/@*[name()='a:value']=$myparam">
<xsl:copy>
<xsl:apply-templates select="@*" mode="copy"/>
<xsl:apply-templates select="*" />
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
E.g称为蒙山xsltproc的和param myparam
xsltproc --stringparam myparam BBB in.xsl in.xml
它产生如(有希望)预期的输出。
<a:level1 xmlns:a="some:a" xmlns:b="some:b" xmlns:c="some:c" xmlns:d="some:d">
<a:level2>
<b:level3>
<b:date a:value="TODAY">
<c:level4>
<d:level5>
<d:level6 a:value="BBB">
<d:level7 a:value="BBB_BBB">
<d:level8 a:value="XXX/123">
<d:leaf a:value="1505">
<b:leaf1>0.42</b:leaf1>
<b:leaf2>0.42</b:leaf2>
</d:leaf>
</d:level8>
</d:level7>
</d:level6>
</d:level5>
</c:level4>
</b:date>
</b:level3>
</a:level2>
</a:level1>
当你说这是“不工作”,它是如何失败? 正如所写,它似乎复制了所有元素和属性的一个子集。 但是你想要什么输出,例如当$ myparam =“TODAY”时?您尚未明确说明要求。 – 2013-04-10 10:56:24
对不起,我更新了我的问题。谢谢。 – gasparino 2013-04-16 06:01:10