Home > database >  Sorting parent nodes by "name" and child nodes by "checker" in XSLT
Sorting parent nodes by "name" and child nodes by "checker" in XSLT

Time:11-22

I'm trying to sort all "attributes" by "name" in XSLT. That worked. Now each "attribute" still has child nodes "constraint", which I would also like to sort according to what is in "checker", e.g. "MinOccurs", "ColumnPrecision" etc.

Unfortunately I don't have much experience with XSLT. How do I have to do that, on the one hand, "attribute" is sorted according to the parent nodes and in "attribute". And sorted below by what is in the child nodes "constraint" after "checker"?

This works for sorting for parent notes "attribute":


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

But I want also sort the child nodes "constraint" in the parent nodes "attribute". Parameter for sorting should be the content of "checker=" in the "constraint" child node.

Here is an example of the structure:


    <attributes>
        <attribute documentIdentifier="false" name="Attribute02">
                <constraints>
                <constraint checker="MinOccurs">
                    <settings>1</settings>
                </constraint>
                <constraint checker="ColumnPrecision">
                    <settings>12</settings>
                </constraint>
                <constraint checker="ColumnScale">
                    <settings>0</settings>
                </constraint>
            </constraints>
            <visibility document="false" hitlist="false" search="false"/>
        </attribute>
        <attribute documentIdentifier="false" name="Attribute01">
            <constraints>
                <constraint checker="ColumnPrecision">
                    <settings>12</settings>
                </constraint>
                <constraint checker="ColumnScale">
                    <settings>0</settings>
                </constraint>
            </constraints>
        </attribute>
    </attributes>

I hope you can help me to find a solution, how not only the "attributes" can be sorted alphabetically, but also the contained child nodes "constraint" according to the designations, which are behind "checker=".

This should be the result:

<attributes>
    <attribute documentIdentifier="false" name="Attribute01">
        <constraints>
            <constraint checker="ColumnPrecision">
                <settings>12</settings>
            </constraint>
            <constraint checker="ColumnScale">
                <settings>0</settings>
            </constraint>
        </constraints>
    </attribute>
    <attribute documentIdentifier="false" name="Attribute02">
        <constraints>
            <constraint checker="ColumnPrecision">
                <settings>12</settings>
            </constraint>
            <constraint checker="ColumnScale">
                <settings>0</settings>
            </constraint>
            <constraint checker="MinOccurs">
                <settings>1</settings>
            </constraint>
        </constraints>
        <visibility document="false" hitlist="false" search="false"/>
    </attribute>
</attributes>

I hope you can help me.

CodePudding user response:

AFAICT, you want to do:

<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="/attributes">
    <xsl:copy>
        <xsl:apply-templates select="attribute">
            <xsl:sort select="@name"/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

<xsl:template match="constraints">
    <xsl:copy>
        <xsl:apply-templates select="constraint">
            <xsl:sort select="@checker"/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Note that this assumes attributes has no child nodes other than attribute, and likewise constraints has only constraint children.

  • Related