如何对“p”元素条目进行排序

问题描述

我尝试对 p 元素条目进行排序,例如(1(a),1.1,1,1(a)-(b))。如何对条目进行排序?
输入

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <sec>
        <title>Title 1</title>
        <p><bold>10(a)</bold></p>
        <p><bold>10</bold></p>
        <p><bold>10(b)</bold></p>
        <p><bold>10(d)</bold></p>
        <p><bold>10(c)-(d)</bold></p>
        <p><bold>1</bold></p>
        <sec>
            <title>Title 1(a)</title>
            <p><bold>14(1)</bold></p>
            <p><bold>14</bold></p>
            <p><bold>14(2)</bold></p>
            <p><bold>14(4)</bold></p>
            <p><bold>14(3)-(4)</bold></p>
            <p><bold>10.1</bold></p>
            <p><bold>10</bold></p>
            <p><bold>10.8</bold></p>
        </sec>
    </sec>
</root>

预期产出

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <sec>
    <title>Title 1</title>
    <p><bold>1</bold></p>
    <p><bold>10</bold></p>
    <p><bold>10(a)</bold></p>
    <p><bold>10(b)</bold></p>
    <p><bold>10(c)-(d)</bold></p>
    <p><bold>10(d)</bold></p>
    <sec>
      <title>Title 1(a)</title>
      <p><bold>10</bold></p>
      <p><bold>10.1</bold></p>
      <p><bold>10.8</bold></p>
      <p><bold>14</bold></p>
      <p><bold>14(1)</bold></p>
      <p><bold>14(2)</bold></p>
      <p><bold>14(3)-(4)</bold></p>
      <p><bold>14(4)</bold></p>
    </sec>
  </sec>
</root>

XSLT

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="sec">
    <xsl:copy>
        <xsl:copy-of select="title"/>
        <xsl:for-each select="p">
            <xsl:sort select="bold" data-type="number" order="ascending"/>
            <xsl:apply-templates/>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

解决方法

也许以下 XSLT 3 捕获了您的意图:

  <xsl:template match="sec">
    <xsl:copy>
      <xsl:for-each-group select="*" group-adjacent=". instance of element(p)">
        <xsl:choose>
          <xsl:when test="current-grouping-key()">
            <xsl:apply-templates select="sort(current-group(),'http://www.w3.org/2013/collation/UCA?numeric=yes')"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:apply-templates select="current-group()"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>

假设身份转换已作为基本模板就位,例如在 XSLT 3 中声明为 <xsl:mode on-no-match="shallow-copy"/>