2012-10-12 122 views
1

我正在嘗試創建一個從另一個xml設置的標頭詳細XML文檔。使用XSLT對XML進行分組

源XML文檔:

<items> 
    <item> 
     <col1>H</col1> 
     <col2>header1</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail1.1</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail1.2</col2> 
    </item> 
    <item> 
     <col1>H</col1> 
     <col2>header2</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail2.1</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail2.2</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail2.3</col2> 
    </item> 
</items> 

所需的輸出:

<xml> 
    <transaction> 
     <items> 
      <item> 
       <col1>H</col1> 
       <col2>header1</col2> 
      </item> 
      <item> 
       <col1>D</col1> 
       <col2>detail1.1</col2> 
      </item> 
      <item> 
       <col1>D</col1> 
       <col2>detail1.2</col2> 
      </item> 
     </items> 
    </transaction> 
    <transaction> 
     <items> 
      <item> 
       <col1>H</col1> 
       <col2>header2</col2> 
      </item> 
      <item> 
       <col1>D</col1> 
       <col2>detail2.1</col2> 
      </item> 
      <item> 
       <col1>D</col1> 
       <col2>detail2.2</col2> 
      </item> 
      <item> 
       <col1>D</col1> 
       <col2>detail2.3</col2> 
      </item> 
     </items> 
    </transaction> 
</xml> 

我試圖XSLT:

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> 
    <xsl:template match="/ | node() | @* | comment() | processing-instruction()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="item[col1='H']"> 
     <transaction> 
      <xsl:apply-templates/> 
     </transaction> 
    </xsl:template> 
</xsl:transform> 

回答

0

這種轉變

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

<xsl:key name="kItemByCol2Num" match="item[starts-with(col2, 'detail')]" 
    use="substring-before(substring-after(col2, 'detail'), '.')"/> 

<xsl:key name="kItemByCol2Num" match="item[starts-with(col2, 'header')]" 
    use="substring-after(col2, 'header')"/> 

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

<xsl:template match= 
"item 
    [starts-with(col2, 'header') 
    and 
    generate-id() 
    = 
    generate-id(key('kItemByCol2Num', substring-after(col2, 'header'))[1]) 
    ]"> 
    <transaction> 
    <xsl:copy-of select="key('kItemByCol2Num', substring-after(col2, 'header'))"/> 
    </transaction> 
</xsl:template> 
<xsl:template match="item"/> 
</xsl:stylesheet> 

當所提供的XML文檔應用:

<items> 
    <item> 
     <col1>H</col1> 
     <col2>header1</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail1.1</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail1.2</col2> 
    </item> 
    <item> 
     <col1>H</col1> 
     <col2>header2</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail2.1</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail2.2</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail2.3</col2> 
    </item> 
</items> 

產生想要的,正確的結果:

<items> 
    <transaction> 
     <item> 
     <col1>H</col1> 
     <col2>header1</col2> 
     </item> 
     <item> 
     <col1>D</col1> 
     <col2>detail1.1</col2> 
     </item> 
     <item> 
     <col1>D</col1> 
     <col2>detail1.2</col2> 
     </item> 
    </transaction> 
    <transaction> 
     <item> 
     <col1>H</col1> 
     <col2>header2</col2> 
     </item> 
     <item> 
     <col1>D</col1> 
     <col2>detail2.1</col2> 
     </item> 
     <item> 
     <col1>D</col1> 
     <col2>detail2.2</col2> 
     </item> 
     <item> 
     <col1>D</col1> 
     <col2>detail2.3</col2> 
     </item> 
    </transaction> 
</items> 

說明

  1. 正確使用Muenchian方法進行分組。

  2. 正確使用密鑰。

+0

它適用於提供的xml,但是我的要求是在col1上進行分組。我用col2 ='header'和'detail'組成了樣本xml,這樣輸出集就可以區分了。我想用你提供的xslt,但由於我不熟悉key(),我仍然沒有得到所需的輸出。我原來的xml在col2上有不同的值,實際上它有20多列。 – gangt

+0

@gangt,THe提供了「所需的輸出」*沒有*按col1分組!如果你願意,你可能會問一個新的問題 - 目前形式的問題已經完全回答了。如果您在新問題中指定的數據不是您實際擁有的數據,難怪 - 答案將無法使用。 –