2012-05-25 18 views
2

我也有類似的傳入XML某些硬件:循環通過多個序列從STR:令牌化()

<invoice> 
    <field name="item">Item 1;Item 2;Item 3</field> 
    <field name="price">32.0;192.2;12.0</field> 
    <field name="quantity">1;4;2</field> 
</invoice> 

,我需要類似轉換成這樣:

<invoice> 
    <item> 
    <desc>Item 1</desc> 
    <price>32.0</price> 
    <quantity>1</quantity> 
    </item> 
    <item> 
    <desc>Item 1</desc> 
    <price>192.0</price> 
    <quantity>4</quantity> 
    </item> 
    <item> 
    <desc>Item 3</desc> 
    <price>12.0</price> 
    <quantity>2</quantity> 
    </item>  
</invoice> 

目前我我嘗試過str:tokenize(),但主要的問題是構造一個簡單的循環。我對XSLT的知識是很基本的,我正在進行的工作是關於遠:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:str="http://exslt.org/strings"> 
<xsl:output method="xml" indent="yes" version="1.0" encoding="UTF-8" omit-xml-declaration="yes" /> 
<xsl:template match="inovice"> 
    <xsl:param name="separator" select="';'"/> 
    <xsl:param name="desc" select="str:tokenize(field[@name='item'],$separator)"/> 
    <xsl:param name="price" select="str:tokenize(field[@name='price'],$separator)"/> 
    <xsl:param name="quantity" select="str:tokenize(field[@name='quantity'],$separator)"/> 
    <xsl:param name="count" select="count($desc)"/> 
    <!-- some loop goes here --> 
</xsl:template> 
</xsl:stylesheet> 

回答

2

是遍歷所有項目,並選擇對應的價格/數量根據當前位置的簡單的XSLT 2.0樣式表,可能看起來像這樣的:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="invoice"> 
    <xsl:variable name="fields" select="field"/> 
    <invoice> 
     <xsl:for-each select="tokenize(field[@name='item'], ';')"> 
     <xsl:variable name="pos" select="position()"/> 
     <item> 
      <desc> 
      <xsl:value-of select="."/> 
      </desc> 
      <price> 
      <xsl:value-of select="tokenize($fields[@name='price'], ';')[position()=$pos]"/> 
      </price> 
      <quantity> 
      <xsl:value-of select="tokenize($fields[@name='quantity'], ';')[position()=$pos]"/> 
      </quantity>   
     </item> 
     </xsl:for-each> 
    </invoice> 
    </xsl:template> 
</xsl:stylesheet> 

如果你想用EXSLT擴展模塊,樣式表必須只能性能稍微修改使用XSLT 1.0在一起:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:str="http://exslt.org/strings" 
    extension-element-prefixes="str"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="invoice"> 
    <xsl:variable name="fields" select="field"/> 
    <invoice> 
     <xsl:for-each select="str:tokenize(field[@name='item'], ';')"> 
     <xsl:variable name="pos" select="position()"/> 
     <item> 
      <desc> 
      <xsl:value-of select="."/> 
      </desc> 
      <price> 
      <xsl:value-of select="str:tokenize($fields[@name='price'], ';')[position()=$pos]"/> 
      </price> 
      <quantity> 
      <xsl:value-of select="str:tokenize($fields[@name='quantity'], ';')[position()=$pos]"/> 
      </quantity>   
     </item> 
     </xsl:for-each> 
    </invoice> 
    </xsl:template> 
</xsl:stylesheet> 
+0

非常感謝你給我的洞察力。它確實需要什麼。 我使用了xmlns:str =「http://exslt.org/strings」,並用str:tokenize替換了標記。否則Xalan會給出錯誤。 –

+0

不客氣。 :) – Martin

+0

我沒有時間檢查我的想法,但據我瞭解,如果我需要指定xmlns:str,那麼我不使用XSLT-2.0,但1.0。我認爲Xalan可以處理2.0。 –