1

我的 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 文本?

4

2 回答 2

2

因为您的Test元素与 匹配<xsl:template match="soapenv:Body//*">,它在输出中创建一个Test元素,将模板应用于其子元素(复制Hope元素),然后附加一个包含Test元素本身的字符串值的文本节点 - 这是其所有后代文本的连接节点,包括里面的那个Hope

<xsl:value-of>当有问题的元素没有子元素时,您可以通过使唯一触发来解决此问题,或者将其包装在

<xsl:if test="not(*)">

或使用单独的模板soapenv:Body//*[*]

于 2013-02-16T15:16:49.680 回答
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>
于 2013-02-16T15:35:18.043 回答