2012-09-28 130 views
0

如何将所有具有相同名称的元素节点合并为一个保留每个元素的子节点?XQuery:合并相同名称的节点

例输入:

<topic> 
    <title /> 
    <language /> 
    <more-info> 
    <itunes /> 
    </more-info> 
    <more-info> 
    <imdb /> 
    </more-info> 
    <more-info> 
    <netflix /> 
    </more-info> 
</topic> 

输出示例(所有more-info S的折叠到一个单一的元素):

<topic> 
    <title /> 
    <language /> 
    <more-info> 
    <itunes /> 
    <imdb /> 
    <netflix /> 
    </more-info> 
</topic> 

编辑:我正在寻找一种方式来做到这一点而不知道哪些节点名称会再次发生。因此,通过上面的示例,我无法使用仅针对more-info的脚本,因为可能有其他元素也需要应用相同的流程。

回答

1

使用

declare option saxon:output "omit-xml-declaration=yes"; 
<topic> 
    <title /> 
    <language /> 
    <more-info> 
    {for $inf in /*/more-info/node() 
    return $inf 
    } 
    </more-info> 
</topic> 

当这个XQuery的是所提供的XML文档应用:

<topic> 
    <title /> 
    <language /> 
    <more-info> 
    <itunes /> 
    </more-info> 
    <more-info> 
    <imdb /> 
    </more-info> 
    <more-info> 
    <netflix /> 
    </more-info> 
</topic> 

想要的,正确的结果产生

<topic> 
    <title/> 
    <language/> 
    <more-info> 
     <itunes/> 
     <imdb/> 
     <netflix/> 
    </more-info> 
</topic> 
+0

谢谢,这工作,但我一直在寻找因为当我不知道哪些节点会再发生时,可以合并它们。我应该更具体一些;我已经更新了OP。 –

+0

@HughGuiney,在这种情况下,使用XSLT你会更好。 –

0

如果您可以使用它,这对于XSLT来说似乎更好。

XML输入

<topic> 
    <title /> 
    <language /> 
    <more-info> 
     <itunes /> 
    </more-info> 
    <more-info> 
     <imdb /> 
    </more-info> 
    <more-info> 
     <netflix /> 
    </more-info> 
</topic> 

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

    <xsl:template match="/*"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*"/> 
      <xsl:for-each-group select="*" group-by="name()"> 
       <xsl:copy> 
        <xsl:apply-templates select="current-group()/@*"/> 
        <xsl:apply-templates select="current-group()/*"/> 
       </xsl:copy> 
      </xsl:for-each-group> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

XML输出

<topic> 
    <title/> 
    <language/> 
    <more-info> 
     <itunes/> 
     <imdb/> 
     <netflix/> 
    </more-info> 
</topic> 
+0

我可以使用它,但是请你解释为什么XSLT在这里是更好的选择? –

相关问题