0

这是 XML

<?xml version="1.0" encoding="utf-8"?>
<Groups>
    <GroupData ID="xxx" Key="4" Temp="yyy">
        <ItemData ID="zzz" Value="3"/>
    </GroupData>
    <GroupData ID="yyy" Key="4" Temp="yyy">
        <ItemData ID="abc" Value="3"/>
    </GroupData>
    <GroupData ID="zzz" Temp="yyy">
        <ItemData ID="pqr" Value="1982"/>
    </GroupData>
    <GroupData ID="xxx" Key="4" Temp="yyy">
        <ItemData ID="www" Value="1982"/>
    </GroupData>
    <GroupData ID="yyy" Key="4" Temp="yyy">
        <ItemData ID="def" Value="1982"/>
    </GroupData>
    <GroupData ID="zzz" Temp="yyy">
        <ItemData ID="tuv" Value="1982"/>
    </GroupData>
</Groups>

我想变成这样:

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

以此类推其他GroupDataID。

这是我的非工作 XSLT 代码:

<?xml version = "1.0" encoding = "utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="group-data" match="GroupData" use="ItemData"/>
<xsl:template match="/">
  <xsl:for-each select="Groups/GroupData[generate-id() = generate-id(key('group-data', ItemData)[1])]">
    <xsl:copy-of select="key('group-data', ItemData)"/>
  </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

PS 我一直在看这个论坛的Muenchian Method和另一个线程,但我想自己写它,因为我必须将它应用到一个更大、更扭曲的 XML 文档上。

4

1 回答 1

0

首先出错的是你的钥匙

<xsl:key name="group-data" match="GroupData" use="ItemData"/>

这表明您希望按子ItemData元素的内容对GroupData元素进行分组。但是您所有的ItemData元素都没有价值,因此您将只有一个“组”。看起来您实际上想在此处按ID属性进行分组

<xsl:key name="group-data" match="GroupData" use="@ID"/>

现在,在您的xsl:for-each中,您具有获取不同组元素的正确语法,但在循环中,您只想创建第一个不同GroupData的副本,然后复制其中所有项目的子ItemData元素群组。

<xsl:copy>
   <xsl:copy-of select="@*|key('group-data', @ID)/ItemData"/>
</xsl:copy>

试试这个 XSLT

<?xml version = "1.0" encoding = "utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes" />
   <xsl:key name="group-data" match="GroupData" use="@ID"/>
   <xsl:template match="/">
     <xsl:for-each select="Groups/GroupData[generate-id() = generate-id(key('group-data', @ID)[1])]">
         <xsl:copy>
               <xsl:copy-of select="@*|key('group-data', @ID)/ItemData"/>
         </xsl:copy>
     </xsl:for-each>
   </xsl:template>
</xsl:stylesheet>

实际上,如果您要使用标识转换来复制元素并使用模板会更好,这更符合 XSLT 的精神。试试这个:

<?xml version = "1.0" encoding = "utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes" />
   <xsl:key name="group-data" match="GroupData" use="@ID"/>
   <xsl:template match="/">
          <xsl:apply-templates select="Groups/GroupData[generate-id() = generate-id(key('group-data', @ID)[1])]" />
  </xsl:template>

   <xsl:template match="GroupData">
       <GroupData>
            <xsl:apply-templates select="@*|key('group-data', @ID)/ItemData" />
       </GroupData>
  </xsl:template>

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

</xsl:stylesheet>
于 2013-05-20T07:37:26.617 回答