2012-05-30 29 views
1

我有下面的XML输入文件:XSLT分组和留出复制

<mappings> 
    <mapping> 
     <key>6718</key> 
     <value attribute="content_type">Info Page</value> 
    </mapping> 
    <mapping> 
     <key>35905</key> 
     <value attribute="content_type">Press releases</value> 
    </mapping> 
    <mapping> 
     <key>6718</key> 
     <value attribute="content_type">Info Page</value> 
    </mapping> 
    <mapping> 
     <key>36941</key> 
     <value attribute="content_type">Press releases</value> 
    </mapping> 
    <mapping> 
     <key>24920</key> 
     <value attribute="content_type">Press releases</value> 
    </mapping> 
    <mapping> 
     <key>40244</key> 
     <value attribute="content_type">Press releases</value> 
    </mapping> 
    <mapping> 
     <key>36639</key> 
     <value attribute="content_type">Press releases</value> 
    </mapping> 
    <mapping> 
     <key>1861</key> 
     <value attribute="content_type">Press releases</value> 
    </mapping> 
    <mapping> 
     <key>2280</key> 
     <value attribute="content_type">Press releases</value> 
    </mapping> 
    <mapping> 
     <key>42062</key> 
     <value attribute="content_type">Press releases</value> 
    </mapping> 
</mappings> 

我想产生以下XML:

<reductions> 
    <reduction> 
     <group>Info Page</group> 
     <key>6718</key> 
    </reduction> 
    <reduction> 
     <group>Press releases</group> 
     <key>35905</key> 
     <key>36941</key> 
     <key>24920</key> 
     <key>40244</key> 
     <key>36639</key> 
     <key>1861</key> 
     <key>2280</key> 
     <key>42062</key> 
    </reduction> 
</reductions> 

所以从输入XML密钥必须根据输入XML中值节点的值将其分组到输出XML中。 此外,需要删除重复项,输入XML包含值为6718两次的键,输出XML只有一次。

我对Saxon 9 HE使用XSLT 2.0。

有人可以帮我吗?

[编辑]

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:transform 
    version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs"> 

    <xsl:template match="/"> 
     <xsl:variable name="mappings"> 
      <mappings> 
       <xsl:apply-templates select="resource/R"/> 
      </mappings> 
     </xsl:variable> 
     <reductions> 
      <xsl:apply-templates select="$mappings/*"/> 
     </reductions> 
    </xsl:template> 

    <xsl:template match="R"> 
     <mapping> 
      <key><xsl:value-of select="MT[@N='content_id']/@V"/></key> 
      <value> 
       <xsl:attribute name="attribute">content_type</xsl:attribute> 
       <xsl:value-of select="MT[@N='content_type']/@V"/> 
      </value> 
     </mapping> 
     <!--mapping> 
      <key><xsl:value-of select="MT[@N='content_id']/@V"/></key> 
      <value> 
       <xsl:attribute name="attribute">modified_timestamp</xsl:attribute> 
       <xsl:value-of select="format-dateTime(MT[@N='modified_timestamp']/@V, '[Y0001]-[M01]-[D01]')"/> 
      </value> 
     </mapping--> 
    </xsl:template> 

    <xsl:template match="mapping"> 
     <xsl:for-each-group select="." group-by="value"> 
      <reduction> 
       <group><xsl:value-of select="current-grouping-key()"/></group> 
       <xsl:for-each-group select="current-group()/key" group-by="."> 
        <xsl:copy-of select="."/> 
       </xsl:for-each-group> 
      </reduction> 
     </xsl:for-each-group> 
    </xsl:template> 

</xsl:transform> 

回答

4

下面是一个样式表使用for-each-group两次:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:output indent="yes"/> 

<xsl:template match="mappings"> 
    <reductions> 
    <xsl:for-each-group select="mapping" group-by="value"> 
     <reduction> 
     <group><xsl:value-of select="current-grouping-key()"/></group> 
     <xsl:for-each-group select="current-group()/key" group-by="."> 
      <xsl:copy-of select="."/> 
     </xsl:for-each-group> 
     </reduction> 
    </xsl:for-each-group> 
    </reductions> 
</xsl:template> 

</xsl:stylesheet> 

[编辑] 当运行与撒克逊9.4张贴的样式表HE相对于输入

<mappings> 
    <mapping> 
     <key>6718</key> 
     <value attribute="content_type">Info Page</value> 
    </mapping> 
    <mapping> 
     <key>35905</key> 
     <value attribute="content_type">Press releases</value> 
    </mapping> 
    <mapping> 
     <key>6718</key> 
     <value attribute="content_type">Info Page</value> 
    </mapping> 
    <mapping> 
     <key>36941</key> 
     <value attribute="content_type">Press releases</value> 
    </mapping> 
    <mapping> 
     <key>24920</key> 
     <value attribute="content_type">Press releases</value> 
    </mapping> 
    <mapping> 
     <key>40244</key> 
     <value attribute="content_type">Press releases</value> 
    </mapping> 
    <mapping> 
     <key>36639</key> 
     <value attribute="content_type">Press releases</value> 
    </mapping> 
    <mapping> 
     <key>1861</key> 
     <value attribute="content_type">Press releases</value> 
    </mapping> 
    <mapping> 
     <key>2280</key> 
     <value attribute="content_type">Press releases</value> 
    </mapping> 
    <mapping> 
     <key>42062</key> 
     <value attribute="content_type">Press releases</value> 
    </mapping> 
</mappings> 

我得到结果

<reductions> 
    <reduction> 
     <group>Info Page</group> 
     <key>6718</key> 
    </reduction> 
    <reduction> 
     <group>Press releases</group> 
     <key>35905</key> 
     <key>36941</key> 
     <key>24920</key> 
     <key>40244</key> 
     <key>36639</key> 
     <key>1861</key> 
     <key>2280</key> 
     <key>42062</key> 
    </reduction> 
</reductions> 

就我的理解您的要求而言,这是正确的。

+0

这不是预期的结果。我在输入中获得与节点一样多的节点,每个节点只有一个和一个元素。他们根本没有分组。 – mmjmanders

+0

对不起,我不明白你为什么会得到这样的结果。我使用Saxon 9.4进行了测试,现在我的答案中包含的输出结果似乎是您想要的。请提供您使用的XSLT 2.0处理器的详细信息,以及是否有任何细节(如输入中的名称空间)在您的发布中遗漏了。 –

+0

当我运行命令行时它可以工作,但是当从Java应用程序调用它时不起作用。 – mmjmanders