对 xslt 中与文本混合的数字进行排序

问题描述 投票:0回答:1

我需要使用属性“d”按升序对一组文档进行排序。但在这个属性中,数字与字母混合在一起。

属性可以是这样的: d =“11A-1-000003”d =“11-1-000008a”d =“11-16-000009”d =“11-1C-000008”d =“11-9-000002”d =“12- 1-000008a" d="11-15-00014" d="13-1-000007a" d="11-15B-00014a" d="11-24-00043a" d="11-3-000023" d =“11-3-000023a”d =“11-3-000023b”

我尝试了不同的解决方案,但没有运气,顺序不正确。

<xsl:sort select="normalize-space(@d)" data-type="text" order="ascending" case-order="upper-first"/>

<xsl:sort select="replace(normalize-space(@d), '[^\d]', '')" data-type="number" order="ascending"/>

<xsl:sort select="substring-before(normalize-space(@d), '-')" data-type="number"/>
<xsl:sort select="substring-before(substring-after(normalize-space(@d), '-'), '-')" data-type="number"/>
<xsl:sort select="substring-after(substring-after(normalize-space(@d), '-'), '-')" data-type="number"/>
<xsl:sort select="substring-before(normalize-space(@d), '-')" data-type="text"/>
<xsl:sort select="substring-before(substring-after(normalize-space(@d), '-'), '-')" data-type="text"/>
<xsl:sort select="substring-after(substring-after(normalize-space(@d), '-'), '-')" data-type="text"/>
<xsl:sort select="number(tokenize(@d, '-')[1])" data-type="number"/>
<xsl:sort select="number(tokenize(@d, '-')[2])" data-type="number"/>
<xsl:sort select="number(tokenize(@d, '-')[3])" data-type="number"/>
<xsl:sort select="tokenize(normalize-space(@d), '-')[1]"/>
<xsl:sort select="tokenize(normalize-space(@d), '-')[2]"/>
<xsl:sort select="tokenize(normalize-space(@d), '-')[3]"/>

实际结果是:11-3-000023在11-24-00043a之后,但应该在11-2之后, 11-1C-000008 在 11-15B-000008 之后,但应该在 11-1 之后

预期的结果是数字应该优先于字母。 数字是章节,字母是子章节。

作为示例,预期结果是:

d="11-1-000008a" d="11-1C-000008" d="11-3-000023" d="11-3-000023a" d="11-3-000023b" d="11-9-000002" d="11-15-00014" d="11-15B-00014a" d="11-16-000009" d="11-24-00043a" d="11A-1-000003" d="12-1-000008a" d="13-1-000007a"

sorting xslt xslt-2.0
1个回答
0
投票

这是一种解决方案,它使用正则表达式将

@d
值解析为六个单独的标记(数字和非数字),并为每个标记使用单独的
xsl:sort
对文档进行排序。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  
  <xsl:output method="xml" indent="true"/>

  <xsl:template match="documents">
    <xsl:copy>
      <!-- regular expression parses @d values into 6 tokens:
      a numeric token, an optional non-numeric token, an ignored hyphen, 
      a numeric token, an optional non-numeric token, an ignored hyphen, 
      a numeric token, an optional non-numeric token. 
       -->
      <xsl:variable name="parser">(\d+)([^\d]*)-(\d+)([^\d]*)-(\d+)([^\d]*)</xsl:variable>
      <xsl:perform-sort select="*">
        <xsl:sort select="replace(@d, $parser, '$1')" data-type="number"/>
        <xsl:sort select="replace(@d, $parser, '$2')"/>
        <xsl:sort select="replace(@d, $parser, '$3')" data-type="number"/>
        <xsl:sort select="replace(@d, $parser, '$4')"/>
        <xsl:sort select="replace(@d, $parser, '$5')" data-type="number"/>
        <xsl:sort select="replace(@d, $parser, '$6')"/>
      </xsl:perform-sort>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

输入:

<documents>
   <document d="11A-1-000003"/>
   <document d="11-1-000008a"/>
   <document d="11-16-000009"/>
   <document d="11-1C-000008"/>
   <document d="11-9-000002"/>
   <document d="12-1-000008a"/>
   <document d="11-15-00014"/>
   <document d="13-1-000007a"/>
   <document d="11-15B-00014a"/>
   <document d="11-24-00043a"/>
   <document d="11-3-000023"/>
   <document d="11-3-000023a"/>
   <document d="11-3-000023b"/>
</documents>

输出

<documents>
   <document d="11-1-000008a"/>
   <document d="11-1C-000008"/>
   <document d="11-3-000023"/>
   <document d="11-3-000023a"/>
   <document d="11-3-000023b"/>
   <document d="11-9-000002"/>
   <document d="11-15-00014"/>
   <document d="11-15B-00014a"/>
   <document d="11-16-000009"/>
   <document d="11-24-00043a"/>
   <document d="11A-1-000003"/>
   <document d="12-1-000008a"/>
   <document d="13-1-000007a"/>
</documents>
© www.soinside.com 2019 - 2024. All rights reserved.