代码之家  ›  专栏  ›  技术社区  ›  atamanroman

如何在xslt中按十六进制排序?

  •  6
  • atamanroman  · 技术社区  · 14 年前

    我试图用一个包含十六进制值的元素对转换后的输出进行排序。

    <xsl:sort select="Generation/Sirio/Code" data-type="number"/>

    值是普通的旧十六进制: 00 01 02 ... 0A ... FF 但它们是这样分类的: 0A FF 00 01 02

    我怎样才能解决这个问题?

    2 回复  |  直到 14 年前
        1
  •  2
  •   Dimitre Novatchev    14 年前

    这种转变 :

    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
        <xsl:variable name="vZeroes"
         select="'00000000000000000000000000000000000000'"/>
    
     <xsl:template match="node()|@*">
         <xsl:copy>
           <xsl:apply-templates select="node()|@*"/>
         </xsl:copy>
     </xsl:template>
    
     <xsl:template match="/*">
      <xsl:copy>
        <xsl:apply-templates select="*">
           <xsl:sort select=
             "concat(substring($vZeroes,
                               1,
                               string-length($vZeroes)
                              -
                               string-length(@hexVal)
                               ),
                      translate(@hexVal,'abcdef','ABCDEF')
                     )
             "/>
        </xsl:apply-templates>
      </xsl:copy>
     </xsl:template>
    </xsl:stylesheet>
    

    应用于此XML文档时:

    <t>
      <x hexVal="0A"/>
      <x hexVal="0327FE"/>
      <x hexVal="ff5240"/>
      <x hexVal="1BA402"/>
      <x hexVal="C3A214"/>
    </t>
    

    <t>
       <x hexVal="0A"/>
       <x hexVal="0327FE"/>
       <x hexVal="1BA402"/>
       <x hexVal="C3A214"/>
       <x hexVal="ff5240"/>
    </t>
    

    解决方案详细信息

    这个解决方案的唯一假设是十六进制排序键的最大长度是有限的(比如说20)。然后我们使用一个零串,比这个最大长度长。这个 $vZeroes 变量保存这个由零组成的字符串,用于在每个排序键的左边填充零,以便所有排序键具有相同的长度。

        2
  •  1
  •   Eamon Nerbonne    14 年前

    最简单的解决方案

    data-type="number" .

    最好的方法 . XSLT1.0不能很好地处理任意的数据转换,如果您尝试将其用作“通用”字符串处理器,那么最终将得到大型、复杂、难以维护的转换。

    如果你 按文本排序,您需要确保所有数字在左侧用0填充到相同的长度。所有字母必须是同一个大小写(这几乎总是正确的,但是如果您合并来自不同来源的数据,可能会出错。)通常,这些要求在XSLT之外很容易满足。

    一个稍微更一般和更长的解决方案

    translate(my-xpath-expr,'abcdef','ABCDEF')

    如果

    <xsl:sort select="string-length(Generation/Sirio/Code)" data-type="number"/>
    <xsl:sort select="translate(Generation/Sirio/Code,'abcdef','ABCDEF')"/>
    

    0x ".

    然而,如果可能的话,你最好只是确保所有数字的格式相同,并尽可能按文本排序。