2013-10-08 29 views
0

源XML:尋找獨特的節點使用XSLT內部的for-each

<r:root xmlns:r="http://root/"> 
<p:parent xmlns:p="http://parent/"> 
    <p:name>John</name> 
    <p:age>30</age> 
    <c:child xmlns:c="http://child/"> 
     <c:cname>John_child_1</cname> 
     <c:cage/> 
     <c:ItemNumber>1</ItemNumber> 
    </child> 
    <c:child xmlns:c="http://child/"> 
     <c:cname>John_child_2</cname> 
     <c:cage/> 
     <c:ItemNumber>2</ItemNumber> 
    </child> 
    <c:child xmlns:c="http://child/"> 
     <c:cname>John_child_3</cname> 
     <c:cage/> 
     <c:ItemNumber>1</ItemNumber> 
    </child> 
</parent> 
<p:parent> 
    <p:name>Doe</name> 
    <p:age>40</age> 
    <c:child xmlns:c="http://child/"> 
     <c:cname>Doe_child_1</cname> 
     <c:cage/> 
     <c:ItemNumber>2</ItemNumber> 
    </child> 
    <c:child xmlns:c="http://child/"> 
     <c:cname>Doe_child_2</cname> 
     <c:cage/> 
     <c:ItemNumber>2</ItemNumber> 
    </child> 
</parent> 
... 
... 
... 

目標XML:

<root> 
<f:father xmlns:f="http://father/"> 
    <f:name>John</name> 
    <f:age>30</age> 
    <f:UniqueItemNumber>1</UniqueItemNumber> 
    <c:child xmlns:c="http://child/"> 
     <c:cname>John_child_1</cname> 
     <c:cage/> 
     <c:ItemNumber>1</ItemNumber> 
    </child> 
    <c:child xmlns:c="http://child/"> 
     <c:cname>John_child_3</cname> 
     <c:cage/> 
     <c:ItemNumber>1</ItemNumber> 
    </child> 
</father> 
<f:father xmlns:f="http://father/"> 
    <f:name>John</name> 
    <f:age>30</age> 
    <f:UniqueItemNumber>2</UniqueItemNumber> 
    <c:child xmlns:c="http://child/"> 
     <c:cname>John_child_2</cname> 
     <c:cage/> 
     <c:ItemNumber>2</ItemNumber> 
    </child> 
</father> 
<f:father xmlns:f="http://father/"> 
    <f:name>Doe</name> 
    <f:age>40</age> 
    <f:UniqueItemNumber>2</UniqueItemNumber> 
    <c:child xmlns:c="http://child/"> 
     <c:cname>Doe_child_1</cname> 
     <c:cage/> 
     <c:ItemNumber>2</ItemNumber> 
    </child> 
    <c:child xmlns:c="http://child/"> 
     <c:cname>Doe_child_2</cname> 
     <c:cage/> 
     <c:ItemNumber>2</ItemNumber> 
    </child> 
</father> 
.... 
... 

我有一個XML源,我想使用XSLT轉換爲顯示的Target xml。

在源代碼中,我們可以有超過1個父元素,每個元素包含多個子元素。要生成目標,首先我們應該爲每個父母找到所有孩子的ItemNumber的不同清單。因此,應該爲源xml中的每個唯一ItemNumber映射目標xml中的Father元素。你可以說它就像sql的group-by子句,我們在每個Parent的ItemNumber上進行分組。我希望這個例子解釋這種情況。

我一直在嘗試各種各樣的事情,但還沒有達到甚至接近解決方案。我遇到了多個問題,同時形成了一個解決方案: 1.我認爲我不能申請「Muenchian方法」,因爲我需要爲每個Parent找到唯一的ItemNumber。因此,必須在for-each(parent)元素中定義關鍵字。我很困惑。 2.我認爲,我應該有一個頂級的每個(家長)。在裏面,一種確定唯一的ItemNumber的方法。然後,當我嘗試使用獲取父名稱時,我得不到任何內容,因爲當控件位於第二個for-each(uniqueItemNumber)內時,xpath(/ name)isn; t有效。這個問題很難解釋。

我希望我能在這裏得到解決方案。提前致謝。

回答

0

可以使用Muenchian分組在這樣一個元素內分組,訣竅是包含每個父元素獨特的東西作爲分組鍵的一部分。其generate-id()通常是一個很好的候選人。

<xsl:key name="childrenByNumber "match="c:child" 
    use="concat(generate-id(..), '+', c:ItemNumber)"/> 

當你想提取父母中的組您構建查找鍵以同樣的方式:

<xsl:template match="p:parent"> 
    <xsl:variable name="p" select="."/> 
    <xsl:for-each select="c:child[generate-id() = 
     generate-id(key('childrenByNumber', concat(generate-id($p), '+', c:ItemNumber))[1])]"> 
    <f:father xmlns:f="http://father/"> 
     <f:name><xsl:value-of select="$p/p:name"/></f:name> 
     <f:age><xsl:value-of select="$p/p:age"/></f:age> 
     <f:uniqueItemNumber> 
     <xsl:value-of select="c:ItemNumber"/> 
     </f:uniqueItemNumber> 
     <xsl:copy-of select="key('childrenByNumber', concat(generate-id($p), '+', c:ItemNumber))"/> 
    </f:father> 
    </xsl:for-each> 
</xsl:template> 
+0

感謝很多您的答覆伊恩。你能解釋一下,下面這段代碼執行了哪個任務: kapil

+0

@ user2857635這就是在輸出中插入正確的」c:child「元素組(那些在當前父項中具有當前ItemNumber的元素)。 –

+0

謝謝伊恩的解釋。 – kapil