我的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>
我的问题是,为什么我会在Hope元素之后获得额外的asdf文本?
答案 0 :(得分:2)
由于Test
元素与<xsl:template match="soapenv:Body//*">
匹配,后者在输出中创建了Test
元素,因此将模板应用于其子元素(复制Hope
元素)和然后附加一个包含Test
元素本身的字符串值的文本节点 - 这是其所有后代文本节点的串联,包括Hope
内的一个。
你可以通过在有问题的元素没有元素子元素的情况下使<xsl:value-of>
仅触发来解决此问题,方法是将其包装在
<xsl:if test="not(*)">
或使用soapenv:Body//*[*]
答案 1 :(得分:2)
您似乎想要摆脱命名空间。 (为什么?实际上这不应该是必要的!)
考虑一种更惯用的方法。
<!-- 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>