2011-11-01 68 views
1

我有一个包含以下标记的XML文件合并与整合节点含量值

<xml> 
    <content relationship="regula"> 
     **<source attribute1="RSC1985s5c1" attribute2="6(17)"/>** 
     <target attribute1="LRC1985s5c1" attribute1="6(17)1"/> 
    </content> 

    <content relationship="translation-of"> 
     **<source attribute1="RSC1985s5c1" attribute2="6(17)"/>** 
     <target attribute1="LRC1985s5c4" attribute2="6(17)1"/> 
    </content> 

    <content relationship="translation-of"> 
     **<source attribute1="RSC1985s5c2" attribute2="7(17)"/>** 
     <target attribute1="LRC1985s5c2" attribute2="7(17)"/> 
    </content> 

    <content relationship="translation-of"> 
     **<source attribute1="RSC1985s5c1" attribute2="6(17)"/>** 
      <target attribute1="LRC1985s5c6" attribute2="6(17)2"/> 
    </content> 

    </xml> 

什么,我要的是节点的内容合并到一个新的节点,如果ATTRIBUTE1和attrbite2值的源节点是相等的。所以输出应该像

<xml> 
    <transformed relationship="merged"> 
      <source attribute1="RSC1985s5c1" attribute2="6(17)"/> 
      <target attribute1="LRC1985s5c1" attribute2="6(17)1"/> 
      <target attribute1="LRC1985s5c4" attribute2="6(17)1"/> 
      <target attribute1="LRC1985s5c6" attribute2="6(17)2"/> 
    </transformed> 

     <transformed relationship="non-merged"> 
      <source attribute1="RSC1985s5c2" attribute2="7(17)"/> 
      <target attribute1="LRC1985s5c2" attribute2="7(17)"/> 
    </transformed> 
    </xml> 

所以第一个两个节点具有彼此相等源ATTRIBUTE1和attribute2值,这就是为什么我有将它们组合起来作为一个新的节点。源中的第三个节点与其他为什么我分开输出的节点不匹配。我尝试使用foreach循环,但无法得到适当的解决方法。感谢您的帮助,如果我们可以通过使用模板匹配来实现。

具有子节点“源”的相同属性的任何内容节点应该组合在一起,而不管它们的位置如何。的关系将得到改变为合并后的人与非合并项目“合并”这将是“非合并”

+0

@_atif:任何两个“内容”节点与“共同”儿童合并?是否只有两个相邻的“内容”节点要合并?如果两个以上的“内容”节点具有“共同”元素会怎样? “关系”属性是否应该因合并而丢失?这个问题中有太多事情不清楚。请编辑并提供缺少的信息。 –

+0

任何具有相同属性的子节点“源”的内容节点都应该组合在一起,无论它们的位置如何。对于合并后的关系将变为“合并”,非合并后的项目将变为“未合并” – atif

+0

@_atif:嗯,在评论中这是很好的说法,但它属于问题 - 请编辑您的问题并在那里提供这些信息。此外,你没有回复我的问题什么应该是预期的输出id多于两个节点将被合并 - 请在你的问题中提供这样的例子。我绝对不愿意猜测你可能没有想过的事情...... –

回答

1

这可以通过Muenchian分组的

因为你需要对符合两个单独的属性来实现在元素,你可能需要使用一个串联的关键,像这样

<xsl:key name="dupes" 
    match="content/source" 
    use="concat(@attribute1, '|', @attribute2)" /> 

重要的是要选择一个串接字符到两个属性(在这种情况下,管道),可从来没有出现在两个人分开属性值。

通常情况下,每个组中的第一个元素匹配,然后你可以做到这一点

<xsl:apply-templates select="content/source 
    [generate-id() = 
    generate-id(key('dupes', concat(@attribute1, '|', @attribute2))[1])]" /> 

但是,你需要做一些额外的工作,你需要知道哪些元素在该组中有多个项目,并且只包含单个项目。因此,要获得团体与多个项目,您可以执行以下操作:

<xsl:apply-templates select="content/source 
    [generate-id() = 
     generate-id(key('dupes', concat(@attribute1, '|', @attribute2))[1])] 
     [count(key('dupes', concat(@attribute1, '|', @attribute2))) > 1]" /> 

以下是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="dupes" match="content/source" use="concat(@attribute1, '|', @attribute2)"/> 

    <xsl:template match="/xml"> 
     <xsl:copy> 
     <transformed relationship="merged"> 
      <xsl:apply-templates select="content/source[generate-id() = generate-id(key('dupes', concat(@attribute1, '|', @attribute2))[1])][count(key('dupes', concat(@attribute1, '|', @attribute2))) &gt; 1]"/> 
     </transformed> 
     <transformed relationship="non-merged"> 
      <xsl:apply-templates select="content/source[generate-id() = generate-id(key('dupes', concat(@attribute1, '|', @attribute2))[1])][count(key('dupes', concat(@attribute1, '|', @attribute2))) = 1]"/> 
     </transformed> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="source"> 
     <xsl:copy-of select="."/> 
     <xsl:copy-of select="key('dupes', concat(@attribute1, '|', @attribute2))/following-sibling::target[1]"/> 
    </xsl:template> 
</xsl:stylesheet> 

当适用于您的示例XML,下面是输出

<xml> 
    <transformed relationship="merged"> 
     <source attribute1="RSC1985s5c1" attribute2="6(17)"/> 
     <target attribute1="LRC1985s5c1" attribute2="6(17)1"/> 
     <target attribute1="LRC1985s5c4" attribute2="6(17)1"/> 
     <target attribute1="LRC1985s5c6" attribute2="6(17)2"/> 
    </transformed> 
    <transformed relationship="non-merged"> 
     <source attribute1="RSC1985s5c2" attribute2="7(17)"/> 
     <target attribute1="LRC1985s5c2" attribute2="7(17)"/> 
    </transformed> 
</xml>