Xslt:在利用数据之前,重写树以对不同父项中的子属性进行排序

时间:2018-05-08 18:47:22

标签: sorting xslt

我踩到了我想做的一步:

我有什么:



    <cat>
        <cat2>
             <item name="ddd">...</item>
        </cat2>
        <cat3>
             <cat4>
                  <cat5>
                          <item name="aaa">...</item>
                          <item name="fff">...</item>
                  </cat5>
                  <item name="bbb">...</item>
             </cat4>
             <item name="eee">...</item>
        </cat3>
        <item name="ccc">...</item>
    </cat>
&#13;
&#13;
&#13;

我想按项目名称(要导出)对其进行排序,所以对所有&#34; cat&#34;重新排序,例如:

 <cat>
    <cat3>
         <cat4>
              <cat5>
                      <item name="aaa">...</item>
              </cat5>
              <item name="bbb">...</item>
         </cat4>
    </cat3>
    <item name="ccc">...</item>
    <cat2>
         <item name="ddd">...</item>
    </cat2>
    <cat3>
         <item name="eee">...</item>
         <cat4>
              <cat5>
                      <item name="fff">...</item>
              </cat5>
         </cat4>
    </cat3>
</cat>

我不在乎结果是否很长,因为我会将其导出(... | itemName | cat | cat1 | cat2 | ...)但我必须为每个人保留父母,然后获取它们按名称排序,因为导出后排序是非常不可能的。

1 个答案:

答案 0 :(得分:1)

XSLT 3有一个snapshot函数,允许您轻松创建节点及其祖先的副本,因此使用XSLT 3(在开源版本Saxon 9.8 HE中可用于.NET和Java和C / C ++)您至少可以按名称轻松订购item元素,然后分别为每个项重新创建祖先层次结构:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="3.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/*">
      <xsl:copy>
          <xsl:apply-templates select="@*"/>
          <xsl:variable name="sorted-items" as="element(item)*">
              <xsl:perform-sort select="descendant::item">
                  <xsl:sort select="@name"/>
              </xsl:perform-sort>
          </xsl:variable>
          <xsl:sequence select="$sorted-items!root(snapshot())"/>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

您的样本的结果是

<cat>
   <cat>
      <cat3>
         <cat4>
            <cat5>
               <item name="aaa">...</item>
            </cat5>
         </cat4>
      </cat3>
   </cat>
   <cat>
      <cat3>
         <cat4>
            <item name="bbb">...</item>
         </cat4>
      </cat3>
   </cat>
   <cat>
      <item name="ccc">...</item>
   </cat>
   <cat>
      <cat2>
         <item name="ddd">...</item>
      </cat2>
   </cat>
   <cat>
      <cat3>
         <item name="eee">...</item>
      </cat3>
   </cat>
   <cat>
      <cat3>
         <cat4>
            <cat5>
               <item name="fff">...</item>
            </cat5>
         </cat4>
      </cat3>
   </cat>
</cat>

如果您的导出只需要每个项目的祖先并保留兄弟结构并不重要,这可能就足够了。

在线示例位于https://xsltfiddle.liberty-development.net/bFDb2C2