Similar to the previous subelement sort, but I have a few extra layers of nodes. I can't figure out a simple extension to the previous answer that works. http://stackoverflow.com/questions/572854/how-to-sort-a-subelement-of-xml-with-xslt
The simplified input example:
<Iteration>
<Iteration_query-ID>NODE_10008</Iteration_query-ID>
<Iteration_query-def>NODE_10008</Iteration_query-def>
<Iteration_query-len>339</Iteration_query-len>
<Iteration_hits>
<Hit>
<Hit_id>110679166</Hit_id>
<Hit_def>[Roseobacter litoralis Och 149]</Hit_def>
<Hit_len>68</Hit_len>
<Hit_hsps>
<Hsp>
<Hsp_score>300.0</Hsp_score>
<Hsp_evalue>4.94413E-26</Hsp_evalue>
<Hsp_query-from>69</Hsp_query-from>
<Hsp_query-to>272</Hsp_query-to>
</Hsp>
</Hit_hsps>
</Hit>
<Hit>
<Hit_id>114767284</Hit_id>
<Hit_def>[Roseovarius sp. HTCC2601]</Hit_def>
<Hit_len>68</Hit_len>
<Hit_hsps>
<Hsp>
<Hsp_bit-score>127.487</Hsp_bit-score>
<Hsp_score>319.0</Hsp_score>
<Hsp_evalue>3.0968E-28</Hsp_evalue>
<Hsp_query-from>69</Hsp_query-from>
<Hsp_query-to>272</Hsp_query-to>
</Hsp>
</Hit_hsps>
</Hit>
</Iteration_hits>
</Iteration>
I want to sort by one of the Hsp attributes, such as Hsp_score. I've been able to get it to sort, but I can't figure out how to keep it from dropping out some of the Hit nodes:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:import href="identity.xsl"/>
<!--
Iteration/Iteration_hits/Hit/Hit_hsps/Hsp
-->
<xsl:template match="Iteration_hits">
<xsl:copy>
<xsl:apply-templates select="Hit/Hit_hsps/Hsp">
<xsl:sort select="Hsp_score" order="descending"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
-
Would this work?
<xsl:apply-templates select="Hit"> <xsl:sort select="Hit_hsps/Hsp/Hsp_score" order="descending"/> </xsl:apply-templates> -
Tested David's code.
This will work.
<xsl:apply-templates select="Hit"> <xsl:sort select="Hit_hsps/Hsp/Hsp_score" data-type="number" order="descending"/> </xsl:apply-templates>EDIT: Added Dimitre's data-type attribute. Thanks Dimitre!
Jweede : make sure to add the data-type="number" attribute to ensure proper ordering.Dimitre Novatchev : @Jweede this is something important -- not just for show-off. Imagine you find unexpectedly one day the nodes sorted in an unwanted way! BTW your own solution has the same problem. And you even didn't up-vote my answer...Jweede : Thanks Dimitre! I forgot to correct this code. -
There is a slight problem with David's code:
As written, 120 will come after 90, although the sort order is specified as
descending.The proper way to sort with numeric sort keys is illustrated below:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <!-- --> <xsl:param name="pNewType" select="'myNewType'"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <!-- --> <xsl:template match="Iteration_hits"> <xsl:copy> <xsl:apply-templates select="Hit"> <xsl:sort select="Hit_hsps/Hsp/Hsp_score" data-type="number" order="descending"/> </xsl:apply-templates> </xsl:copy> </xsl:template> </xsl:stylesheet>When applied on this XML document:
<Iteration> <Iteration_query-ID>NODE_10008</Iteration_query-ID> <Iteration_query-def>NODE_10008</Iteration_query-def> <Iteration_query-len>339</Iteration_query-len> <Iteration_hits> <Hit> <Hit_id>110679166</Hit_id> <Hit_def>[Roseobacter litoralis Och 149]</Hit_def> <Hit_len>68</Hit_len> <Hit_hsps> <Hsp> <Hsp_score>120.0</Hsp_score> <Hsp_evalue>4.94413E-26</Hsp_evalue> <Hsp_query-from>69</Hsp_query-from> <Hsp_query-to>272</Hsp_query-to> </Hsp> </Hit_hsps> </Hit> <Hit> <Hit_id>114767284</Hit_id> <Hit_def>[Roseovarius sp. HTCC2601]</Hit_def> <Hit_len>68</Hit_len> <Hit_hsps> <Hsp> <Hsp_bit-score>127.487</Hsp_bit-score> <Hsp_score>90.0</Hsp_score> <Hsp_evalue>3.0968E-28</Hsp_evalue> <Hsp_query-from>69</Hsp_query-from> <Hsp_query-to>272</Hsp_query-to> </Hsp> </Hit_hsps> </Hit> </Iteration_hits> </Iteration>the correct result is produced:
<Iteration> <Iteration_query-ID>NODE_10008</Iteration_query-ID> <Iteration_query-def>NODE_10008</Iteration_query-def> <Iteration_query-len>339</Iteration_query-len> <Iteration_hits><Hit> <Hit_id>110679166</Hit_id> <Hit_def>[Roseobacter litoralis Och 149]</Hit_def> <Hit_len>68</Hit_len> <Hit_hsps> <Hsp> <Hsp_score>120.0</Hsp_score> <Hsp_evalue>4.94413E-26</Hsp_evalue> <Hsp_query-from>69</Hsp_query-from> <Hsp_query-to>272</Hsp_query-to> </Hsp> </Hit_hsps> </Hit><Hit> <Hit_id>114767284</Hit_id> <Hit_def>[Roseovarius sp. HTCC2601]</Hit_def> <Hit_len>68</Hit_len> <Hit_hsps> <Hsp> <Hsp_bit-score>127.487</Hsp_bit-score> <Hsp_score>90.0</Hsp_score> <Hsp_evalue>3.0968E-28</Hsp_evalue> <Hsp_query-from>69</Hsp_query-from> <Hsp_query-to>272</Hsp_query-to> </Hsp> </Hit_hsps> </Hit></Iteration_hits> </Iteration>Do note the use of the
data-typeattribute ofxsl:sort.Jweede : I see what you mean. Such a show-off Dimitre. :-)Dimitre Novatchev : @Jweede this is something important -- not just for show-off. Imagine you find unexpectedly one day the nodes sorted in an unwanted way! BTW your own solution has the same problem.Nerdling : I like your answer Dimitre, but that's a lot of reading. is it possible you can post a concise introduction or summary for it (about the size of the other posts)?Dimitre Novatchev : @Nerdling When one does not know some fundamental stuff, a lot of reading is really needed! 90% of all answers on SO suffer from being untested and incomplete. An answer must provide self-contained working code and demonstrate the results when executed on a specific input. The OPs input is long agr.
0 comments:
Post a Comment