XSLT以非字母顺序非数字顺序排序类

时间:2016-07-16 10:00:22

标签: xslt

我已经研究过这个问题,但我发现的建议似乎相当复杂,而且更为一般。也许这种情况有一个更简洁的解决方案,更具体。

我有大量的html文件,如下所示:

xmlns:tools="http://schemas.android.com/tools"

规则#1 我想按照类属性的特定顺序来命令div里面的div class =“a”,这是非字母和非数字的。出于这个例子的目的,让最后的顺序如下:

  • ˚F
  • B'/ LI>
  • C
  • ë
  • d

在我的实例中,列表要长得多。

规则#2 如果对于给定的类属性,有多个节点,则它们应保留与原始文件中相同的顺序,例如:

  • C1
  • C2
  • C3

请注意,在我的实际例子中,这些值不是按字母数字顺序排列的。

规则#3 子节点的顺序不得受到影响,例如:

  • BA
  • BB

请注意,在我的实际例子中,这些值也不是字母数字顺序。

最终输出应如下所示:

FrameLayout

我一开始以为:

  1. 在类属性值前加一个数字,例如将class =“g”重命名为class =“01g”等,
  2. 按照字母数字顺序排序班级
  3. 删除号码,例如将class =“01g”重命名为class =“g”等
  4. 但是我不喜欢这个解决方案,因为它需要太多的转换。

    我真正想要的是提出更优雅的解决方案。也许我会定义一个有序的类值列表,一个聪明的索引会以某种方式将节点置于那个定义的顺序中?

    您是否有任何建议要添加到我的xslt模板?

    <html>
      <head>
        <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
        <title>t</title>
      </head>
      <body>
        <div class="a">
          <div class="f">f1</div>
          <div class="e">e1</div>
          <div class="e">e2</div>
          <div class="g">g</div>
          <div class="c">c1</div>
          <div class="b">
            <div class="ba">ba</div>
            <div class="bb">bb</div>
          </div>
          <div class="c">c2</div>
          <div class="f">f2</div>
          <div class="d">d</div>
          <div class="c">c3</div>
        </div>
        ...
      </body>
    </html>
    

1 个答案:

答案 0 :(得分:2)

AFAICT,你想做类似的事情:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" omit-xml-declaration="yes" 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="div[@class='a']">
    <xsl:variable name="sort-order">gfbced</xsl:variable>
    <xsl:copy>
        <xsl:apply-templates select="@*|node()">
            <xsl:sort select="string-length(substring-before($sort-order, @class))" data-type="number" order="ascending"/>
        </xsl:apply-templates>  
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

要容纳非单个字符的类值,您可以使用:

<xsl:template match="div[@class='a']">
    <xsl:variable name="sort-order">|g|f|b|c|e|d|</xsl:variable>
    <xsl:copy>
        <xsl:apply-templates select="@*|node()">
            <xsl:sort select="string-length(substring-before($sort-order, concat('|', @class, '|')))" data-type="number" order="ascending"/>
        </xsl:apply-templates>  
    </xsl:copy>
</xsl:template>