XSLT - 将自身节点text()放置到属性

时间:2016-04-27 09:15:12

标签: xml xslt xslt-2.0

我有一个样本xml,如下所示,

<doc>
    <para>AAAAA BBB<s/>CCC DDD<l/>EEEE<t/>FFFFF <style>GGGG</style>HHHHHH</para>
</doc>

使用XSLT我必须将其转换为相同的节点树,但是将名称属性添加到名为<para>的{​​{1}}节点,并且它的值应该是'name'的内容文本元件。

所以输出应该是,

<para>

正如您在输出中看到的,应将所有文本节点复制到name属性值a,并且必须删除所有内联元素(<doc> <p name="AAAAA BBB CCC DDD EEEE FFFFF GGGG HHHHHH">AAAAA BBB<s/>CCC DDD<l/>EEEE<t/>FFFFF <style>GGGG</style>HHHHHH</p> </doc> )。并且所有<s/>,<t/>,<l/>,<style><s/><t/>都必须替换为空格。

我已经在xslt之后写了这个,

<l/>

它提供以下输出,

<xsl:template match="p">
        <p name="{abc:process-attr-text(child::node())}">
            <xsl:apply-templates/>
        </p>
    </xsl:template>

    <xsl:function name="abc:process-attr-text">
        <xsl:param name="node"/>

        <xsl:sequence select="$node/text()"/>
    </xsl:function>

如何修改我的功能以获得正确的结果?

2 个答案:

答案 0 :(得分:4)

这有点尴尬,只是使用<p name="{.}">的明显答案是行不通的,因为它只会连接所有后代文本节点,给出AAAAA BBBCCC DDDEEEEFFFFF GGGGHHHHHH

如果要确保在相邻文本节点之间存在XML标记的地方有空格,那么您需要更具创造性。尝试

<p name="{normalize-space(string-join(descendant::text(), ' '))}">

这会在所有文本节点之间加一个额外的空格,然后normalize会将两个相邻的空格压缩为一个。

答案 1 :(得分:1)

为什么不简单:

<xsl:template match="para">
    <p name="{.}">
        <xsl:apply-templates/>
    </p>
</xsl:template>