Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
248 views
in Technique[技术] by (71.8m points)

XSLT: Sorting authors based on surnames and based on CHARMAP character also

My code is unable to sort the names, when 'use-character-maps' module is used. Without CharMap, I am able to get the required result.

Sorting should be based on CharMap character also, i.e., 'Anupam' should be the third author in result (my code is listing him at the end). Please suggest. (XSLT2 vesrion)

XML:

<article>
 <aug>
    <author><surname>Akhil</surname><fnm>GH</fnm></author>
    <author><surname>Kishan</surname><fnm>TR</fnm></author>
    <author><surname>&#x000C1;nupam</surname><fnm>TP</fnm></author>
    <author><surname>Abhi</surname><fnm>TD</fnm></author>
 </aug>
</article>

XSLT:

 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" use-character-maps="chars"/>
    <xsl:character-map name="chars">
        <xsl:output-character character="&#x000C1;" string="A"/>
    </xsl:character-map>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="aug">
        <aug>
        <xsl:for-each select="author">
            <xsl:sort select="surname"/>
            <au><xsl:apply-templates select="surname"/><xsl:text> </xsl:text><xsl:apply-templates select="fnm"/></au>
        </xsl:for-each>
        </aug>
    </xsl:template>
</xsl:stylesheet>

Required Result:

<article>
 <aug>
    <author><surname>Abhi</surname><fnm>TD</fnm></author>
    <author><surname>Akhil</surname><fnm>GH</fnm></author>
    <author><surname>Anupam</surname><fnm>TP</fnm></author>
    <author><surname>Kishan</surname><fnm>TR</fnm></author>
 </aug>
</article>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Character maps are a serialization feature and serialization only happens as a final step after a result tree has been created. So you would need to run two separate transformations, one that applies your character map (for instance with an identity transformation) and creates a result file, a second that consumes the result file and does the sorting.

As an alternative, and depending on the XSLT processor you use, for instance with Saxon 9, you might want to check whether using a collation solves the problem of the sorting:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" use-character-maps="chars"/>
    <xsl:character-map name="chars">
        <xsl:output-character character="&#x000C1;" string="A"/>
    </xsl:character-map>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="aug">
        <aug>
        <xsl:for-each select="author">
            <xsl:sort select="surname" collation="http://saxon.sf.net/collation?lang=en&amp;ignore-modifiers=yes"/>
            <au><xsl:apply-templates select="surname"/><xsl:text> </xsl:text><xsl:apply-templates select="fnm"/></au>
        </xsl:for-each>
        </aug>
    </xsl:template>
</xsl:stylesheet>

See http://saxonica.com/documentation/index.html#!extensibility/collation for details.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...