为什么XSLT产生意想不到的结果
问题描述:
我的XSLT:为什么XSLT产生意想不到的结果
<xsl:template match="node()">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="soapenv:Body//*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@* | *" />
<xsl:value-of select="." />
</xsl:element>
</xsl:template>
<xsl:template match="soapenv:Body//@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
输入:
<soapenv:Body>
<Test asdf="asdfasdf">
<Hope>asdf</Hope>
</Test>
</soapenv:Body>
输出:
<Test asdf="asdfasdf">
<Hope>asdf</Hope>
asdf
</Test>
我的问题是,为什么我收到后,多余的ASDF文本希望元素?
答
因为你Test
元素由<xsl:template match="soapenv:Body//*">
,这在输出创建Test
元素匹配,应用模板到其子(复制Hope
元素),然后追加包含Test
元素本身的字符串值的文本节点 - 这是所有后代文本节点的连接,包括Hope
中的一个。
你可以通过使当有问题的元件不具有子元素的<xsl:value-of>
只火,无论是在
<xsl:if test="not(*)">
包裹,或通过使用一个单独的模板soapenv:Body//*[*]
答
您解决这个问题似乎想要摆脱名称空间。 (为什么?这实际上不是必须的!)
考虑一个更习惯的方法。
<!-- 1) always try to start off with the identity template -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<!-- 2) only create templates for nodes that need extra processing -->
<xsl:template match="soapenv:*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node() | @*" />
</xsl:element>
</xsl:template>
结果与你输入:
<Body>
<Test asdf="asdfasdf">
<Hope>asdf</Hope>
</Test>
</Body>
编辑:如果你只是想在开始正文内容输出,使用:
<xsl:template match="/">
<xsl:apply-templates select="soapenv:Envelope/soapenv:Body/*" />
</xsl:template>