2010-03-15 80 views
1

使用XSL:如何组合或合并分组节点?

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0"> 
    <xsl:output method="xml"/> 
    <xsl:template match="/"> 
     <records> 
      <record> 
       <!-- Group record by bigID, for further processing --> 
       <xsl:for-each-group select="records/record" group-by="bigID"> 
        <xsl:sort select="bigID"/> 
        <xsl:for-each select="current-group()"> 
         <!-- Create new combined record --> 
         <bigID> 
          <!-- <xsl:value-of select="."/> --> 
          <xsl:for-each select="."> 
           <xsl:value-of select="bigID"/> 
          </xsl:for-each> 
         </bigID> 
         <text> 
          <xsl:value-of select="text"/> 
         </text> 
        </xsl:for-each> 
       </xsl:for-each-group> 
      </record> 
     </records> 
    </xsl:template> 
</xsl:stylesheet> 

我试图改变:

<?xml version="1.0" encoding="UTF-8"?> 
<records> 
    <record> 
     <bigID>123</bigID> 
     <text>Contains text for 123</text> 
     <bigID>456</bigID> 
     <text>Some 456 text</text> 
     <bigID>123</bigID> 
     <text>More 123 text</text> 
     <bigID>123</bigID> 
     <text>Yet more 123 text</text> 
    </record> 
</records> 

到:

<?xml version="1.0" encoding="UTF-8"?> 
<records> 
    <record> 
     <bigID>123 
      <text>Contains text for 123</text> 
      <text>More 123 text</text> 
      <text>Yet more 123 text</text> 
     </bigID> 
     <bigID>456 
      <text>Some 456 text</text> 
     </bigID> 
    </record> 
</records> 

现在,我刚刚上市的分组<bigID> S,个别。我错过了分组后的步骤,我将分组的<bigID>节点组合在一起。我的怀疑是我需要使用“键”功能,但我不确定。

感谢您的任何帮助。

+0

您的输入和输出xml格式不正确。这使得输出格式不明确。 – 2010-03-16 15:42:11

回答

0

这里是有用XSLT 2.0转化

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:key name="kTextforId" match="text" 
     use="preceding-sibling::bigID[1]"/> 

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

    <xsl:template match="record"> 
    <record> 
    <xsl:for-each-group select="bigID" group-by="."> 
    <bigID> 
     <xsl:sequence select="current-grouping-key()"/> 

     <xsl:copy-of select= 
     "key('kTextforId', current-grouping-key())"/> 
    </bigID> 
    </xsl:for-each-group> 
    </record> 
    </xsl:template> 
</xsl:stylesheet> 

当所提供的XML文档进行,有用的结果被产生。

+0

我以为我在寻找Lachlan Roche的代码在第二个例子中给出的输出。然而,最终结果是我需要的输出是由Dimitre的代码创建的。非常感谢您的帮助!非常感谢。 – LOlliffe 2010-03-16 19:03:57

-1

在XSLT 2.0中,您不需要按键进行分组。

由于您只是复制组中的text元素,因此可以移除内部的for-each元素。

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

    <xsl:output method="xml" indent="yes" /> 

    <xsl:template match="/"> 
     <records> 
      <record> 
       <xsl:for-each-group select="records/record/bigID" group-by="."> 
        <xsl:sort select="." data-type="number" /> 
        <bigID> 
         <xsl:value-of select="." /> 
         <xsl:copy-of select="current-group()/following-sibling::text[1]" /> 
        </bigID> 
       </xsl:for-each-group> 
      </record> 
     </records> 
    </xsl:template> 

</xsl:stylesheet> 

如果你不是要输出的bigID元素,然后他们的文本元素,然后我的循环将被替换如下。

<xsl:for-each-group select="records/record/bigID" group-by="."> 
    <xsl:sort select="." data-type="number" /> 
    <xsl:copy-of select="." /> 
    <xsl:copy-of select="current-group()/following-sibling::text[1]" /> 
</xsl:for-each-group>