Ravi Kumar
Ravi Kumar

Reputation: 993

Concatenate multiple attributes in one with XSL

I have an input XML looks like following.

<?xml version="1.0" encoding="UTF-8"?>
<topic title="My Topic" subtopic="My SubTopic">
    <table title="My Table" media="print" role="center">
        <thead></thead>
        <tbody></tbody>
    </table>
</topic>

I want it to be translated with XSL as following.

<?xml version="1.0" encoding="UTF-8"?>
<topic title="My Topic" subtitle="My Subtopic">
    <table title="My Table" outputclass="print center">
        <thead></thead>
        <tbody></tbody>
    </table>
</topic>

If you notice any other attribute of table must be concatenated in one attribute named outputclass But only other attribute of table not of the topic.

I have an XSL like this -

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    exclude-result-prefixes="xsl xsi">

    <xsl:output method="xml" indent="yes" omit-xml-declaration="no"
        standalone="no" doctype-public="-//OASIS//DTD DITA Composite//EN" doctype-system="topic.dtd"/>

    <!-- Generic element -->

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

    <xsl:template match="table">
        <table>
            <xsl:apply-templates select="@role | @media" mode="table.att"/>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates />
        </table>
    </xsl:template>

    <xsl:template match="@*">
        <xsl:if test="local-name(.)!='noNamespaceSchemaLocation'">
            <xsl:attribute name="{local-name()}">
                <xsl:value-of select="."/>
            </xsl:attribute>
        </xsl:if>
    </xsl:template>

   <xsl:template match="@*" mode="table.att">
        <xsl:choose>
            <xsl:when test="local-name() = 'role'">
                <xsl:attribute name="outputclass">
                    <xsl:value-of select="."></xsl:value-of>
                </xsl:attribute>
            </xsl:when>
            <xsl:otherwise>
                <!-- <xsl:apply-templates select="."/> -->
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

As expected, it doesn't do the trick. Will you please help me with this. I think i need to send all the attributes together in order to concatenate it but i am not sure how to do that.

Upvotes: 0

Views: 998

Answers (2)

Rupesh_Kr
Rupesh_Kr

Reputation: 3445

Try this

    <xsl:template match="table">
        <table>
            <xsl:apply-templates select="@title"/>
            <xsl:if test="@role and @media">
            <xsl:attribute name="outputclass">
                <xsl:value-of select="concat(@media, ' ', @role)"/>
            </xsl:attribute>    
            </xsl:if>
            <xsl:apply-templates />
        </table>
</xsl:template>

Upvotes: 1

michael.hor257k
michael.hor257k

Reputation: 117165

any other attribute of table must be concatenated in one attribute named outputclass But only other attribute of table not of the topic.

Try it this way:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="table">
    <xsl:copy>
        <xsl:copy-of select="@title"/>
        <xsl:attribute name="outputclass">
            <xsl:for-each select="@*[not(name()='title')]">
                <xsl:value-of select="." />
                <xsl:if test="position()!=last()">
                    <xsl:text> </xsl:text>
                </xsl:if>
            </xsl:for-each>
        </xsl:attribute>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Upvotes: 0

Related Questions