这是所需的转换:
<xsl:stylesheet 版本="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:z="内联:text.xml"
排除结果前缀=“z”
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<z:过滤器>
<根>
<E1 a="1"></E1>
<E2></E2>
<E5>
<SE51></SE51>
<SE52></SE52>
</E5>
</根>
</z:过滤器>
<xsl:variable name="vFilter" select=
"document('')/*/z:filter"/>
<xsl:模板匹配="/">
<xsl:apply-templates select="*[name()=name($vFilter/*)]">
<xsl:with-param name="pFiltNode" select="$vFilter/*"/>
</xsl:apply-templates>
</xsl:模板>
<xsl:template match="*">
<xsl:param name="pFiltNode"/>
<xsl:复制>
<xsl:copy-of select="@*"/>
<xsl:for-each select="text() | *">
<xsl:选择>
<xsl:when test="self::text()">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:否则>
<xsl:变量名="vFiltNode"
select="$pFiltNode/*[name()=name(current())]"/>
<xsl:apply-templates select="self::node()[$vFiltNode]">
<xsl:with-param name="pFiltNode" select="$vFiltNode"/>
</xsl:apply-templates>
</xsl:否则>
</xsl:选择>
</xsl:for-each>
</xsl:copy>
</xsl:模板>
</xsl:样式表>
当此转换应用于以下 XML 文档时(原始文件加上 <SE511>SEV11</SE511>
证明过滤适用于任何级别:
<根>
<E1 a="1">V1</E1>
<E2>V2</E2>
<E3>V3</E3>
<E5>
<SE51>SEV1</SE51>
<SE511>SEV11</SE511>
<SE52>SEV2</SE52>
</E5>
<E6>
<SE61>SEV3</SE61>
<SE62>SEV4</SE62>
</E6>
</根>
产生了想要的结果:
<根>
<E1 a="1">V1</E1>
<E2>V2</E2>
<E3>V3</E3>
<E5>
<SE51>SEV1</SE51>
<SE511>SEV11</SE511>
<SE52>SEV2</SE52>
</E5>
<E6>
<SE61>SEV3</SE61>
<SE62>SEV4</SE62>
</E6>
</根>
请注意此解决方案的以下详细信息:
- 模板仅适用于过滤文档中具有匹配节点的元素,也适用于此类元素的所有文本节点。
- 匹配元素的模板作为参数传递给过滤器文档中的相应节点。
- 将模板应用于元素子时,会找到其对应的节点并将其作为预期参数传递。
尽情享受吧!