2016-11-19 70 views
1

有一些使用xsl:key對項目進行分組的示例,但這些示例不適用於我的場景。如何使用XSLT對按順序排列的xml元素進行分組?

每組與列1 =「H」應該被命名<transaction>,並且所有與列1中的項目=「d」之後的「H」應該是<transaction>作爲<item>內,直到它到達下一個「H」。然後它以相同的規則重複。

問題:這些值用雙引號引起來,但輸出不應該有雙引號。

<root> 
    <row> 
     <column1>"H"</column1> 
     <column2>"2016-09-09"</column2> 
    </row> 
    <row> 
     <column1>"D"</column1> 
     <column2>"Conference Services Meeting Package"</column2> 
    </row> 
    <row> 
     <column1>"D"</column1> 
     <column2>"Audio Visual Meeting Package"</column2> 
    </row> 
    <row> 
     <column1>"H"</column1> 
     <column2>"2016-09-09"</column2> 
    </row> 
    <row> 
     <column1>"D"</column1> 
     <column2>"Meeting Package Lunch"</column2> 
    </row> 
    <row> 
     <column1>"D"</column1> 
     <column2>"Marinated Roasted Olives</column2> 
    </row> 
    <row> 
     <column1>"D"</column1> 
     <column2>"Mezza Plate Humus with Smoked Paprika Butter"</column2> 
    </row> 
    <row> 
     <column1>"D"</column1> 
     <column2>"Pastry Bread Block Loaf Bread"</column2> 
    </row> 
</root> 

輸出:

<xml> 
    <transaction> 
     <item>Conference Services Meeting Package</item> 
     <item>Audio Visual Meeting Package</item> 
    </transaction> 
    <transaction> 
     <item>Meeting Package Lunch</item> 
     <item>Marinated Roasted Olives</item> 
     <item>Mezza Plate Humus with Smoked Paprika Butter</item> 
     <item>Pastry Bread Block Loaf Bread</item> 
    </transaction> 
</xml> 

回答

3

這種轉變

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:key name="kFollowing" match='row[column1=&apos;"D"&apos;]' 
      use='generate-id(preceding-sibling::row[column1=&apos;"H"&apos;][1])'/> 

    <xsl:template match="/*"> 
    <xml> 
     <xsl:apply-templates select='row[column1=&apos;"H"&apos;]'/> 
    </xml> 
    </xsl:template> 

    <xsl:template match="row"> 
    <transaction> 
     <xsl:apply-templates select="key('kFollowing', generate-id())/column2"/> 
    </transaction> 
    </xsl:template> 

    <xsl:template match="column2"> 
    <item><xsl:value-of select= 
    'concat(translate(substring(.,1,1),&apos;"&apos;,""), 
      substring(.,2, string-length(.) -2), 
      translate(substring(.,string-length()),&apos;"&apos;,""))'/></item> 
    </xsl:template> 
</xsl:stylesheet> 

時所提供的XML文檔應用:

<root> 
    <row> 
     <column1>"H"</column1> 
     <column2>"2016-09-09"</column2> 
    </row> 
    <row> 
     <column1>"D"</column1> 
     <column2>"Conference Services Meeting Package"</column2> 
    </row> 
    <row> 
     <column1>"D"</column1> 
     <column2>"Audio Visual Meeting Package"</column2> 
    </row> 
    <row> 
     <column1>"H"</column1> 
     <column2>"2016-09-09"</column2> 
    </row> 
    <row> 
     <column1>"D"</column1> 
     <column2>"Meeting Package Lunch"</column2> 
    </row> 
    <row> 
     <column1>"D"</column1> 
     <column2>"Marinated Roasted Olives</column2> 
    </row> 
    <row> 
     <column1>"D"</column1> 
     <column2>"Mezza Plate Humus with Smoked Paprika Butter"</column2> 
    </row> 
    <row> 
     <column1>"D"</column1> 
     <column2>"Pastry Bread Block Loaf Bread"</column2> 
    </row> 
</root> 

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

<xml> 
    <transaction> 
     <item>Conference Services Meeting Package</item> 
     <item>Audio Visual Meeting Package</item> 
    </transaction> 
    <transaction> 
     <item>Meeting Package Lunch</item> 
     <item>Marinated Roasted Olives</item> 
     <item>Mezza Plate Humus with Smoked Paprika Butter</item> 
     <item>Pastry Bread Block Loaf Bread</item> 
    </transaction> 
</xml> 

說明

  1. 所有對應"D"<column2>元素定義爲它們相應的(最近的前一個)"H"<column1>元件的generate-id()的功能的

  2. 將第一個和最後一個字符從(僅當它們是引用時)"翻譯爲空字符串。因此"Marinated Roasted Olives被正確處理,儘管它不會以引用結束 - 這很可能是偶然的錯誤。

  3. <xsl:for-each>(甚至嵌套!)指令。

+0

完美。它也刪除了雙引號。 – gangt

+0

@gangt,是的,人們可以用XSLT做所有事情。特別是XSLT 2.0和3.0非常強大。 –

2

嘗試這種方式:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

<xsl:key name="tx" match="row[column1='&quot;D&quot;']" use="generate-id(preceding-sibling::row[column1='&quot;H&quot;'][1])" /> 

<xsl:template match="/root"> 
    <xml> 
     <xsl:for-each select="row[column1='&quot;H&quot;']"> 
      <transaction> 
       <xsl:for-each select="key('tx', generate-id())"> 
        <item> 
         <xsl:value-of select="column2"/> 
        </item> 
       </xsl:for-each> 
      </transaction> 
     </xsl:for-each> 
    </xml> 
</xsl:template> 

</xsl:stylesheet> 

這解決了分組相鄰的項目的問題。刪除雙引號的問題相當微不足道,可以通過使用substring()函數輕鬆解決。如果您無法使其工作,請發佈單獨的問題。

+0

Works awesome。我會嘗試substring()或某些東西來刪除雙引號。我正在考慮xslt中的vbscript函數。一旦我完成了,我會在這裏更新它。 – gangt

相關問題