【问题标题】:Wrong XSLT code?错误的 XSLT 代码?
【发布时间】:2013-05-20 07:19:54
【问题描述】:

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

以其他GroupData id 依此类推。

这是我的非工作 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>

附:我一直在查看 Muenchian Method 和该论坛的另一个主题,但我想自己编写它,因为我必须将它应用到更大、更扭曲的 XML 文档上。

【问题讨论】:

    标签: xml xslt grouping xslt-1.0


    【解决方案1】:

    首先出错的是你的钥匙

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

    实际上,如果您使用identity transform 来复制元素并使用更符合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>
    

    【讨论】:

    • 你确定吗?我在xslttest.appspot.com 测试了我的代码,对我来说它看起来不错.....
    • 不,我的错,没关系。但我得到它就像&lt;GroupData ID="xxx" Key="4" Temp="yyy"&gt; &lt;ItemData ID="zzz" Value="3"&gt; &lt;/ItemData&gt; &lt;ItemData ID="www" Value="1982"&gt; &lt;/ItemData&gt; &lt;/GroupData&gt; 我希望它是&lt;GroupData ID="xxx" Key="4" Temp="yyy"&gt; &lt;ItemData ID="zzz" Value="3" /&gt; &lt;ItemData ID="www" Value="1982" /&gt; &lt;/GroupData&gt; 简而言之:&lt;ItemData to be closed like this /&gt; 但没有单独的标签。
    • 我添加了 xsl 输出语句,这可能会有所作为
    • 你能澄清一下&lt;xsl:template match="@*|node()"&gt; &lt;xsl:copy&gt; &lt;xsl:apply-templates select="@*|node()"/&gt; &lt;/xsl:copy&gt; &lt;/xsl:template&gt;的目的和模板吗?
    • 这是 XSLT 身份转换,这是 XSLT 中相当基本的设计模式,用于复制现有节点,但为您提供了覆盖它的灵活性。谷歌“xslt 身份转换”了解更多信息。
    猜你喜欢
    • 1970-01-01
    • 2018-12-21
    • 2016-10-30
    • 2014-04-21
    • 2015-09-22
    • 2012-07-31
    • 2021-08-14
    • 1970-01-01
    • 2023-03-29
    相关资源
    最近更新 更多