Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSLT - How to combine XSLT files

Tags:

xml

xslt

Is there a simple way of combining XSLT's. I am new to XSLT, and i getting the hang of how to create them and the funny ways of using them to get my desired outcome. However at the moment I am able to use one XSLT to convert my output into the desired output; BUT then straight after it i have another, and another. Each XSLT changes the output from one thing to another.

For example, and these are simple XSLTs to illustrate the issue:

XSLT 1:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:r="http://www.castiron.com/response" exclude-result-prefixes="r">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/root">
        <xsl:element name="imageScene7Response"  xmlns="http://www.castiron.com/burberry/digitalcatalogue/response">
            <xsl:element name="rcode">0</xsl:element>
            <xsl:element name="rmessage">success</xsl:element>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="payload"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="/root/payload">
        <xsl:if test="not(productId = preceding-sibling::payload/productId)">

            <xsl:element name="payload" xmlns="http://www.castiron.com/burberry/digitalcatalogue/response">
                <xsl:element name="productId">
                    <xsl:value-of select="productId"/>
                </xsl:element>
                <xsl:for-each select="../payload[productId = current()/productId]">
                    <xsl:choose>
                        <xsl:when test="type = '0' and preceding-sibling::payload/type = type and productId = preceding-sibling::payload/productId">
                            <xsl:element name="alternativeImages">
                                <xsl:value-of select="url"/>
                            </xsl:element>
                        </xsl:when>
                        <xsl:when test="type = '0'">
                            <xsl:element name="mainImage">
                                <xsl:value-of select="url"/>
                            </xsl:element>
                        </xsl:when>
                        <xsl:when test="type &gt; '0' and type &lt; '70'">
                            <xsl:element name="alternativeImages">
                                <xsl:value-of select="url"/>
                            </xsl:element>
                        </xsl:when>
                        <xsl:when test="type = '70'">
                            <xsl:element name="video">
                                <xsl:value-of select="url"/>
                            </xsl:element>
                        </xsl:when>
                        <xsl:when test="type = '80'">
                            <xsl:element name="lookbookImages">
                                <xsl:value-of select="url"/>
                            </xsl:element>
                        </xsl:when>
                        <xsl:when test="type = 'sw'">
                            <xsl:element name="swatchImages">
                                <xsl:value-of select="url"/>
                            </xsl:element>
                        </xsl:when>
                    </xsl:choose>
                </xsl:for-each>
            </xsl:element>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

Then:

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

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

    <xsl:template match=
        "*[not(@*|*|comment()|processing-instruction()) 
        and normalize-space()=''
        ]"/>
</xsl:stylesheet>

Then some other logic in other XSLT.

Is it as easy as putting the templates one below another in a single combined XSLT?

XML SNIPT

<?xml version="1.0"?>
<root>
    <payload>
        <productId>11111</productId>
        <type>0</type>
        <url>https://11111</url>
    </payload>
    <payload>
        <productId>11111</productId>
        <type>1</type>
        <url>https://11111</url>
    </payload>
    <payload>
        <productId>11111</productId>
        <type>1</type>
        <url></url>
    </payload>
    <payload>
        <productId>22222</productId>
        <type>0</type>
        <url>https://22222</url>
    </payload>
    <payload>
        <productId>22222</productId>
        <type>1</type>
        <url>https://22222</url>
    </payload>
    <payload>
        <productId>22222</productId>
        <type>sw</type>
        <url>https://22222</url>
    </payload>
    <payload>
        <productId>22222</productId>
        <type>sw</type>
        <url></url>
    </payload>
</root>

This isnt the best example, but it will work!

like image 339
mmkd Avatar asked Dec 12 '25 12:12

mmkd


1 Answers

The answer is: It depends

If you have multiple XSL Templates then it is possible that it was intended for them to be applied sequentially to the XML - so, for example, if you have 3 XSLT's, it could be that the first is applied to the original document, the second to the result of the first transformation, and the third to the result of the second transformation.

This is known as the pipeline approach - the XML flows along an XSLT pipeline, being repeatedly transformed until a result comes out of the other end and is a perfectly valid approach.

If the XSLT's were designed to be applied sequentially, then it is best to leave them that way - mixing them together into a giant XSLT is possible, but can be very tricky to manipulate and maintain as you have to pass XML node sets from template to template. This approach is discussed here, although I disagree with the author's conclusion that this a purer approach.

In the example above, you have 2 clear XSLT's. The first is clearly structural - it's designed to transform the structure of the XML response into another XML document. The second XSLT you have is almost a utility XSLT - it appears to be designed to strip out anything that isn't an attribute or attribute. In this instance, it would probably be best to apply them in order to the XML response message.

like image 187
dash Avatar answered Dec 15 '25 23:12

dash



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!