2011-04-18 306 views
1

我試圖使用XSLT從平面XML文件創建分層XML文件,但不確定最佳方法是什麼。使用XSLT將平面XML結構更改爲層次結構

例如我需要

<root> 
<inventory bag="1" fruit="apple"/> 
<inventory bag="1" fruit="banana"/> 
<inventory bag="2" fruit="apple"/> 
<inventory bag="2" fruit="orange"/> 
</root> 

轉換爲

<inventory> 
<baglist> 
<bag id="1"/> 
<bag id="2"/> 
</baglist> 

<bag id="1"> 
<fruit id="apple"/> 
<fruit id="banana"/> 
</bag> 

<bag id="2"> 
<fruit id="apple"/> 
<fruit id="orange"/> 
</bag> 
</inventory> 

N個袋/水果

回答

0

inventory元件基於它們bag屬性的值:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="byBag" match="root/inventory" use="@bag" /> 
    <xsl:template match="/"> 
     <inventory> 
      <baglist> 
       <xsl:apply-templates mode="baglist" /> 
      </baglist> 
      <xsl:apply-templates /> 
     </inventory> 
    </xsl:template> 
    <xsl:template 
     match="root/inventory[generate-id() = 
          generate-id(key('byBag', @bag)[1])]" 
         mode="baglist"> 
     <bag id="{@bag}" /> 
    </xsl:template> 

    <xsl:template 
     match="root/inventory[generate-id() = 
          generate-id(key('byBag', @bag)[1])]"> 
     <bag id="{@bag}"> 
      <xsl:apply-templates select="key('byBag', @bag)" 
       mode="details" /> 
     </bag> 
    </xsl:template> 

    <xsl:template match="inventory" mode="details"> 
     <fruit id="{@fruit}" /> 
    </xsl:template> 
</xsl:stylesheet> 
+1

謝謝,所以如果我明白這個正確,生成-ID()返回一個唯一的ID爲當前節點,並且生成-ID (key(stuff)[1])用給定的bagid返回第一個節點的唯一標識符。這樣,每個獨特的bagid只有一個節點將與模板匹配。 – 2011-04-18 19:30:30

+0

@N。岸 - 正是。然後,當我們將模板應用到'key('byBag',@bag)'時,我們指定一個'mode',這樣我們就可以處理組中的所有項目,而無需重新匹配僅選擇第一個項目的模板。這種技術被稱爲Muenchian方法進行分組。 – 2011-04-18 19:47:42

+0

+1正確答案。 – 2011-04-18 20:44:38

0

的xsl:for-each您的節點兩次,或使用xsl:template不同的模式。