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

Posted

技术标签:

【中文标题】Xslt:在利用数据之前重写树以对不同父母中的子属性进行排序【英文标题】:Xslt : rewrite tree to sort child attribute in different parents before exploit data 【发布时间】:2018-10-18 19:19:57 【问题描述】:

我在我想做的事情上磕磕绊绊:

我有什么:

    <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>

我想按项目名称(要导出)对其进行排序,因此所有“猫”都为排序而重写,例如:

 <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|...) 但我必须为每个人保留父母,并让他们按顺序排列名称,因为导出后排序是完全不可能的。

【问题讨论】:

如果可能的话,您是否需要维护兄弟姐妹,或者您是否可以为导出而生存,结果在xsltfiddle.liberty-development.net/bFDb2C2 中,这只是(使用XSLT 3)按@987654325 对所有item 元素进行排序@ 属性,然后为每个项目分别输出每个快照(即item 及其所有祖先的副本)? 把它贴在答案上,我给你一个“+”!谢谢..当我读到你的答案时,我为简单的方式而笑! 34k > 42k 行很好! 【参考方案1】:

XSLT 3 有一个snapshot 函数,允许您使用 XSLT 3 轻松创建节点及其祖先的副本(在用于 .NET 和 Java 和 C/C++ 的开源版本 Saxon 9.8 HE 中可用)您至少可以轻松地按名称对 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。

【讨论】:

以上是关于Xslt:在利用数据之前重写树以对不同父母中的子属性进行排序的主要内容,如果未能解决你的问题,请参考以下文章

在未指定出现顺序时处理 XSLT 中的子标记

如何获取具有相同名称的元素并根据 XSLT 中的子节点值对它们进行排序

如何使用“OR”组合多个条件以对数据框进行子集化?

如果值匹配,XSLT 会更改兄弟元素的子元素值

java-协变返回类型

java-协变返回类型