EnexoOnoma
EnexoOnoma

Reputation: 8836

How to echo the elements of an XML in a predefined order using XSLT?

How can I output the XML elements in a predefined order? A possible solution of an array style it would be great if there is something like this.

I have a lot of XMLs with different names for elements that will be transformed the same time but as you can see they will all echoed the same. My problem is that their order is not correct and I want them in the same order just like

id, name, description, price, image, url, category, category_id, shopid

This is my XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:include href="identity.xsl"/>

    <xsl:template match="/*">
        <products>
            <xsl:for-each select="file">
                <xsl:apply-templates 
                    select="document(.)/*//product">
                    <xsl:with-param name="file" select="."/>
                </xsl:apply-templates>
            </xsl:for-each>
        </products>
    </xsl:template>

    <xsl:template match="product">
        <xsl:param name="file"/>
        <xsl:copy>

            <xsl:apply-templates select="@*"/>

            <xsl:if test="not(id)">
                <id><xsl:value-of select="@id"/></id>
            </xsl:if>

            <xsl:apply-templates select="node()"/>

            <catid><xsl:value-of select="category/@id"/></catid>
            <shopid><xsl:value-of select="$file"/></shopid>

        </xsl:copy>
    </xsl:template>


<xsl:template match="title">
  <name>
        <xsl:apply-templates select="node() | @*" />
  </name>
</xsl:template>
<xsl:template match="price_with_vat">
  <price>
        <xsl:apply-templates select="node() | @*" />
  </price>
</xsl:template>
<xsl:template match="link">
  <url>
        <xsl:apply-templates select="node() | @*" />
  </url>
</xsl:template>

    <xsl:template match="category/@id
        | product/@id | availability | manufacturer | shipping | sku | ssku | thumbnail | stock | weight | mpn | instock"/>

</xsl:stylesheet>

Upvotes: 1

Views: 298

Answers (1)

Emiliano Poggi
Emiliano Poggi

Reputation: 24816

Because you are using the Identity Transformation, you can define the order of the output elements by applying the templates singularly. Example:

<xsl:template match="product">
    <xsl:param name="file"/>
    <xsl:copy>

        <xsl:apply-templates select="@*"/>

        <xsl:if test="not(id)">
            <id><xsl:value-of select="@id"/></id>
        </xsl:if>

        <xsl:apply-templates select="name"/>
        <xsl:apply-templates select="description"/>
        <xsl:apply-templates select="price"/>
        <xsl:apply-templates select="image"/>
        <xsl:apply-templates select="url"/>
        <xsl:apply-templates select="category"/>

        <catid><xsl:value-of select="category/@id"/></catid>
        <shopid><xsl:value-of select="$file"/></shopid>

    </xsl:copy>
</xsl:template>

Upvotes: 1

Related Questions