xml - 在 xml/xslt 中分组/合并相同节点的子节点

标签 xml xslt merge nodes

我是 XSLT 的新手,手动更改它会花费很多时间。

<GroupData ID="xxx" Key="4" Temp="yyy">
 <ItemData ID="zzz" Value="3"/>
</GroupData>

<GroupData ID="xxx" Key="4" Temp="yyy">
 <ItemData ID="www" Value="1982"/>
</GroupData>

我希望将这些多个 GroupData 节点的子节点放在同一组中,即

<GroupData ID="xxx" Key="4" Temp="yyy">
 <ItemData ID="zzz" Value="3"/>
 <ItemData ID="www" Value="1982"/>
</GroupData>

所以我需要在 GroupData 的 ID 和 Key 属性(这些在文件中有所不同)上合并/组合/匹配它们。还有一些没有 Key 属性。我怎样才能做到这一点?我阅读了一些其他线程(例如,在 C# 中,但我没有它)并且我检查了 W3 学校,但这些都是非常基本的例子。我正在使用最新的 XML Tools 2.3.2 r908 unicode (beta4) for Notepad++ 来应用可能的转换(不知道它是否支持 XSLT2.0 或 XSLT1.0)。

编辑:在尝试了下面的建议和各种事情之后我被卡住了,因为它有多个级别并且可能没有唯一的 ID: ...

最佳答案

如果是 XSLT 2.0,那么您可以使用嵌套的 <xsl:for-each-group>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <Groups>
      <xsl:for-each-group select="/Groups/GroupData" group-by="@ID">
        <xsl:for-each-group select="current-group()" group-by="if(@Key) then @Key else 'no key'">
          <GroupData>
            <!-- Copy attributes off the *first* GroupData element in the group -->
            <xsl:copy-of select="current-group()[1]/@*"/>
            <!-- Copy ItemData children from *all* GroupData elements in the group -->
            <xsl:copy-of select="current-group()/ItemData" />
          </GroupData>
        </xsl:for-each-group>
      </xsl:for-each-group>
    </Groups>
  </xsl:template>
</xsl:stylesheet>

(我假设您的输入文件有一个根元素 <Groups> 并且不使用 namespace )。

如果是 XSLT 1.0,则需要使用 Muenchian Grouping :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:key name="group-data" match="GroupData" use="concat(@ID, '___', @Key)" />
  <xsl:template match="/">
    <Groups>
      <!--
      Iterate over a node set containing just one GroupData element for
      each combination of ID and Key
      -->
      <xsl:for-each select="/Groups/GroupData[count( . | key('group-data', concat(@ID, '___', @Key))[1]) = 1]">
        <GroupData>
          <!-- Copy attributes from the "prototype" GroupData -->
          <xsl:copy-of select="@*"/>
          <!--
          Copy ItemData children from *all* GroupData elements with matching
          ID/Key
          -->
          <xsl:copy-of select="key('group-data', concat(@ID, '___', @Key))/ItemData" />
        </GroupData>
      </xsl:for-each>
    </Groups>
  </xsl:template>
</xsl:stylesheet>

在这里,我通过创建合成 key 来基于 ID 和 Key 属性执行单个分组传递。 {ID}___{Key} 的值.

关于xml - 在 xml/xslt 中分组/合并相同节点的子节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11900006/

相关文章:

tsql - 我可以在 SQL Server 2005 中使用 MERGE 语句吗?

svn - 在颠覆中合并合并是一个问题吗?

sql - MERGE 语句与外键约束冲突

xml - 使用 XSLT 删除额外的组级别

xslt - 在哪里可以找到XSLT的静态/动态代码分析工具?

xml - XSLT - 如何修剪 xsl :value-of expressions 中的所有值

android如何在右侧设置复选框图标?

C# 计算 SEPA (XML) 付款文件的 SHA256 值

java - 如何将此 XML 文件解析为 MySQL 表?

android - 自定义状态栏