2011-11-01 73 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>