glove40
glove40

Reputation: 45

XSLT - remove value and add attribute

When a node has the attribute class="deleted", I want to add the value of a node into an attribute called text.

This input:

<element class="deleted" >
    <span>Example</span>
</element>

Should create this output:

<element class="deleted" text="&ltspan>Example&lt/span>" /> **Edit**

The .xsl I use is:

<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
</xsl:template>

<xsl:template match="node()[@class = 'deleted']">
    <xsl:copy>
        <xsl:attribute name="text">
            <xsl:value-of select="child::node()" />
        </xsl:attribute>
        <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
</xsl:template>

and the output is not as wanted it is like:

<element text="Example" class="deleted"><span>Example</span></element>

The problem is I don't know how to remove the value and get the spantags into the attribute text

Upvotes: 1

Views: 130

Answers (1)

kumesana
kumesana

Reputation: 2490

To remove the value:

Just don't apply templates after on the value you've copied, but only on the attributes.

<xsl:template match="node()[@class = 'deleted']">
    <xsl:copy>
        <xsl:apply-templates select="@*" />
        <xsl:attribute name="text">
            <xsl:value-of select="child::node()" />
        </xsl:attribute>
    </xsl:copy>
</xsl:template>

To put the value with its tags inside the attribute, you pretty much need to serialize it to text. You could define a template in charge of that:

<xsl:template mode="serialize-to-text" match="text()">
    <xsl:copy/>
</xsl:template>

<xsl:template mode="serialize-to-text" match="*">
    <xsl:value-of select="concat('&lt;', name(), '>')"/>
    <xsl:apply-templates mode="serialize-to-text" select="node()" />
    <xsl:value-of select="concat('&lt;/', name(), '>')"/>
</xsl:template>

and call it like that:

<xsl:template match="node()[@class = 'deleted']">
    <xsl:copy>
        <xsl:attribute name="text">
            <xsl:apply-templates mode="serialize-to-text" select="node()" />
        </xsl:attribute>
    </xsl:copy>
</xsl:template>

Upvotes: 1

Related Questions