Rudramuni TP
Rudramuni TP

Reputation: 1278

Sort the info based on given sequence order

Please suggest how to sort the info, based on given sort sequence (Seq.xml).

Here fetching info from folder where files' name should have 'Sort##.xml' formats. Output should be sort based on DOI number as sequnce given in external file 'D:\Sort\Seq.xml'.

Input XMLs:

D:\Sort\Sort01.xml

<article>
<fm>
    <title>The solar system</title>
    <aug><au>Rudramuni TP</au></aug>
    <doi>10.11/MPS.0.10.11</doi>
</fm>
<body><text>The text</text></body>
</article>

D:\Sort\Sort02.xml

<article>
<fm>
    <title>The Galaxy</title>
    <aug><au>Kishan TR</au></aug>
    <doi>10.11/MPS.0.10.2</doi>
</fm>
<body><text>The text</text></body>
</article>

D:\Sort\Sort03.xml

<article>
<fm>
    <title>The Pluto</title>
    <aug><au>Kowshik MD</au></aug>
    <doi>10.11/MPS.0.10.10</doi>
</fm>
<body><text>The text</text></body>
</article>

Sequence info in D:\Sort\Seq.xml

<root>
<toc>
    <seq seq="1"><art-id>10.11/MPS.0.10.2</art-id></seq>
    <seq seq="2"><art-id>10.11/MPS.0.10.11</art-id></seq>
    <seq seq="3"><art-id>10.11/MPS.0.10.10</art-id></seq>
</toc>
</root>

XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:variable name="varCollection">

<xsl:copy-of select="
    collection('file:///D:/Sort/?select=Sort*.xml; recurse=yes')
    [matches(document-uri(.),'Sort/Sort[0-9][0-9].xml')]"/>
</xsl:variable><!-- to fetch info from folder 'Sort*.xml' s -->

<xsl:variable name="docSeq" select="document('D:/Sort/Seq.xml')"/><!--In this file, sequnce info is there -->

<!--xsl:key name="kSeq" match="$docSeq/root/toc/seq/@seq" use="art-id"/--><!-- I tried with key, but unable to get the required sequence -->

<xsl:template match="root">
    <xsl:for-each select="$varCollection/article">
        <!--xsl:sort select="key('kSeq', fm/doi)"/-->
        <art>
            <title><xsl:value-of select="fm/title"/></title>
            <Name><xsl:value-of select="fm/aug/au"/></Name>
            <DOI><xsl:value-of select="fm/doi"/></DOI>
        </art><xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Required Sequence

<art><title>The Galaxy</title><Name>Kishan TR</Name><DOI>10.11/MPS.0.10.2</DOI></art>
<art><title>The solar system</title><Name>Rudramuni TP</Name><DOI>10.11/MPS.0.10.11</DOI></art>
<art><title>The Pluto</title><Name>Kowshik MD</Name><DOI>10.11/MPS.0.10.10</DOI></art>

Upvotes: 1

Views: 393

Answers (2)

michael.hor257k
michael.hor257k

Reputation: 117073

You could also do this from the opposite direction:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>

<xsl:variable name="varCollection">
    <xsl:sequence select="collection('file:///D:/Sort/?select=Sort*.xml; recurse=yes')
    [matches(document-uri(.),'Sort/Sort[0-9][0-9].xml')]"/>
</xsl:variable>

<xsl:variable name="docSeq" select="document('D:/Sort/Seq.xml')"/>

<xsl:key name="article" match="article" use="fm/doi" />

<xsl:template match="root">
    <xsl:for-each select="$docSeq/root/toc/seq">
        <xsl:sort select="@seq" data-type="number" order="ascending"/>
        <xsl:apply-templates select="key('article', art-id, $varCollection)"/>
     </xsl:for-each>    
</xsl:template>

<xsl:template match="article">
    <art>
        <title><xsl:value-of select="fm/title"/></title>
        <Name><xsl:value-of select="fm/aug/au"/></Name>
        <DOI><xsl:value-of select="fm/doi"/></DOI>
    </art>
</xsl:template>

</xsl:stylesheet>

Note that the output lacks a root element.

Upvotes: 2

Martin Honnen
Martin Honnen

Reputation: 167696

I think you want

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="varCollection" select="
    collection('file:///D:/Sort/?select=Sort*.xml; recurse=yes')
    [matches(document-uri(.),'Sort/Sort[0-9][0-9].xml')]"/>


<xsl:variable name="docSeq" select="document('file:///D:/Sort/Seq.xml')"/><!--In this file, sequnce info is there -->

<xsl:key name="kSeq" match="root/toc/seq" use="art-id"/>

<xsl:template match="root">
    <xsl:for-each select="$varCollection/article">
        <xsl:sort select="key('kSeq', fm/doi, $docSeq)/xs:integer(@seq)"/>
        <art>
            <title><xsl:value-of select="fm/title"/></title>
            <Name><xsl:value-of select="fm/aug/au"/></Name>
            <DOI><xsl:value-of select="fm/doi"/></DOI>
        </art>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Upvotes: 3

Related Questions