2012-11-04 247 views
0

我想通過xslt使用php將xml文件轉換爲另一個文件。 在輸出上我需要一些調整,但我不知道如何調整我的xsl樣式表。使用XSLT將XML轉換爲XML php

感謝您的幫助

在輸出

必要的調整:

  • 動態計數添加到像<category1> <category2>類別元素...
  • 增加產品/顏色/ COLOR的元件尺寸的全部內容/ AVAILABLE_SIZE到<$color>元素像<green>S:M:L:XL</green> <orange>L:M</orange>
  • 將動態計數添加到圖像元素,如<image1> <image2>

源XML:

<?xml version="1.0" encoding="utf-8"?> 
<PRODUCTS> 
<PRODUCT> 
    <CODE>19</CODE> 
    <NAME>daisy</NAME> 
    <MANUFACTURER>79</MANUFACTURER> 
    <DESCRIPTION>t-shirt</DESCRIPTION> 
    <SIZES></SIZES> 
    <PRICE>33.33</PRICE> 
    <PRICE_AKCIA>24.17</PRICE_AKCIA> 
    <CATEGORY_ID>42</CATEGORY_ID> 
    <CATEGORIES> 
    <CATEGORY>clothes</CATEGORY> 
    <CATEGORY>t-shirt</CATEGORY> 
    <CATEGORY>latest</CATEGORY> 
    </CATEGORIES> 
    <COLORS> 
    <COLOR> 
    <NAME>green</NAME> 
    <IMAGE>http://www.xyz.com/userfiles/daisy_green.png</IMAGE> 
    <AVAILABLE_SIZES> 
    <SIZE>S</SIZE> 
    <SIZE>M</SIZE> 
    </AVAILABLE_SIZES> 
    <SIZES> 
    <SIZE>S</SIZE> 
    <SIZE>M</SIZE> 
    <SIZE>L</SIZE> 
    <SIZE>XL</SIZE> 
    </SIZES> 
    </COLOR> 
    <COLOR> 
    <NAME>orange</NAME> 
    <IMAGE>http://www.xyz.com/userfiles/daisy_orange.png</IMAGE> 
    <AVAILABLE_SIZES> 
    <SIZE>L</SIZE> 
    <SIZE>M</SIZE> 
    </AVAILABLE_SIZES> 
    <SIZES> 
    <SIZE>S</SIZE> 
    <SIZE>M</SIZE> 
    <SIZE>L</SIZE> 
    <SIZE>XL</SIZE> 
    </SIZES> 
    </COLOR> 
    </COLORS> 
</PRODUCT> 
</PRODUCTS> 

XSL樣式表:

<?xml version="1.0" encoding="utf-8"?> 
<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:template match="/"> 
    <xsl:element name="products"> 
     <xsl:apply-templates select="PRODUCTS/PRODUCT"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="PRODUCTS/PRODUCT"> 
    <xsl:element name="product"> 
     <xsl:element name="id"> 
      <xsl:value-of select="CODE"/> 
     </xsl:element> 
     <xsl:element name="name"> 
      <xsl:value-of select="NAME"/> 
     </xsl:element> 
     <xsl:element name="model"> 
      <xsl:value-of select="CODE"/> 
     </xsl:element> 
     <xsl:element name="manufacturer"> 
      <xsl:value-of select="MANUFACTURER"/> 
     </xsl:element> 
     <xsl:element name="category_id"> 
      <xsl:value-of select="CATEGORY_ID"/> 
     </xsl:element> 
     <xsl:apply-templates select="CATEGORIES"/> 
     <xsl:element name="description"> 
      <xsl:value-of select="DESCRIPTION"/> 
     </xsl:element> 
     <xsl:element name="price"> 
      <xsl:value-of select="PRICE"/> 
     </xsl:element> 
     <xsl:element name="special"> 
      <xsl:value-of select="PRICE_AKCIA"/> 
     </xsl:element> 
     <xsl:apply-templates select="COLORS/COLOR"/> 
     <xsl:apply-templates select="COLORS"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="CATEGORIES"> 
    <xsl:for-each select="CATEGORY">  
     <xsl:element name="category"> 
     <xsl:value-of select="."/> 
     </xsl:element> 
    </xsl:for-each> 
</xsl:template> 

<xsl:template match="COLORS"> 
    <xsl:for-each select="COLOR/NAME">  
     <xsl:variable name="color" select="." /> 
     <xsl:element name="{$color}"> 
     <xsl:apply-templates select="COLOR/AVAILABLE_SIZES"/> 
     </xsl:element> 
    </xsl:for-each> 
</xsl:template> 

<xsl:template match="COLORS/COLOR"> 
    <xsl:for-each select="IMAGE">  
     <xsl:element name="image"> 
     <xsl:value-of select="."/> 
     </xsl:element> 
    </xsl:for-each> 
</xsl:template> 

<xsl:template match="COLOR/AVAILABLE_SIZES"> 
    <xsl:for-each select="SIZE">  
     <xsl:value-of select="."/>: 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 

結果:

<?xml version="1.0" encoding="UTF-8"?> 
<products> 
    <product> 
    <id>19</id> 
    <name>daisy</name> 
    <model>19</model> 
    <manufacturer>79</manufacturer> 
    <category_id>42</category_id> 
    <category>clothes</category> 
    <category>t-shirt</category> 
    <category>latest</category> 
    <description>t-shirt</description> 
    <price>33.33</price> 
    <special>24.17</special> 
    <image>http://www.xyz.com/userfiles/daisy_green.png</image> 
    <image>http://www.xyz.com/userfiles/daisy_orange.png</image> 
    <green/> 
    <orange/> 
    </product> 
</products> 
+0

您好!你能否加上你的預期產出,因爲這會讓你更清楚你需要什麼?謝謝! –

回答

0

如果你想擁有動態命名的元素,你可以使用屬性值指定元素名稱的模板。

所以,如果你想類別1類別2等,而不是僅僅類別你這樣做

<xsl:element name="category{position()}"> 

大括號表示這是要evalulated的表達式。

但是,如果你要直接用你的圖片代碼做到這一點,你會看到他們都以1

<xsl:template match="COLORS/COLOR"> 
    <xsl:for-each select="IMAGE">  
     <xsl:element name="image{position()}"> 
     <xsl:value-of select="."/> 
     </xsl:element> 
    </xsl:for-each> 
</xsl:template> 

這是因爲你所得到的IMAGE的位置後綴元素在COLOR元素內。真的你想要父母的位置COLOR元素。相反,在這裏匹配元素可能會更好,那麼您可以獲取元素的位置。

<xsl:template match="COLORS"> 
    <xsl:for-each select="COLOR">  
     <xsl:element name="image{position()}"> 
     <xsl:value-of select="IMAGE"/> 
     </xsl:element> 
    </xsl:for-each> 
</xsl:template> 

當然,這意味着你最終有兩個模板匹配COLORS所以你可能希望將它們組合。但是,其他模板存在問題。您正在迭代顏色/名稱,這意味着您將位於循環內的名稱元素上。因此,當您嘗試選擇COLOR/AVAILABLE_SIZES時,它正在當前元素下面查找它們,它們不存在。你應該這樣做

<xsl:template match="COLORS"> 
    <xsl:for-each select="COLOR">  
     <xsl:variable name="color" select="NAME" /> 
     <xsl:element name="{$color}"> 
     <xsl:apply-templates select="AVAILABLE_SIZES"/> 
     </xsl:element> 
    </xsl:for-each> 

    <!-- Code to do images from above --> 
</xsl:template> 

其他一些事情要注意。如果您需要動態元素名稱(如上所示),您只需要使用xsl:元素,否則直接輸出該元素。

此外,在許多情況下,您所做的只是將大寫名稱轉換爲小寫。這可能是簡單的有這個

<xsl:template match="*"> 
    <xsl:element name="{translate(
     local-name(), 
     'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
     'abcdefghijklmnopqrstuvwxyz')}"> 
     <xsl:apply-templates /> 
    </xsl:element> 
</xsl:template> 

一個通用模板這會減少你需要編寫的代碼。當您想要將元素名稱更改爲完全不同的東西時,您只需要特定的模板。

試試下面的XSLT

<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:template match="*"> 
     <xsl:element name="{translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')}"> 
     <xsl:apply-templates/> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="CODE"> 
     <id> 
     <xsl:value-of select="."/> 
     </id> 
    </xsl:template> 

    <xsl:template match="PRICE_AKCIA"> 
     <special> 
     <xsl:value-of select="."/> 
     </special> 
    </xsl:template> 

    <xsl:template match="CATEGORIES"> 
     <xsl:for-each select="CATEGORY"> 
     <xsl:element name="category{position()}"> 
      <xsl:value-of select="."/> 
     </xsl:element> 
     </xsl:for-each> 
    </xsl:template> 

    <xsl:template match="COLORS"> 
     <xsl:for-each select="COLOR"> 
     <xsl:variable name="color" select="NAME"/> 
     <xsl:element name="{$color}"> 
      <xsl:apply-templates select="AVAILABLE_SIZES"/> 
     </xsl:element> 
     </xsl:for-each> 
     <xsl:for-each select="COLOR"> 
     <xsl:element name="image{position()}"> 
      <xsl:value-of select="IMAGE"/> 
     </xsl:element> 
     </xsl:for-each> 
    </xsl:template> 

    <xsl:template match="AVAILABLE_SIZES"> 
     <xsl:for-each select="SIZE"> 
     <xsl:if test="position() > 1">:</xsl:if> 
     <xsl:value-of select="."/> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

當適用於您的示例XML,下面是輸出

<products> 
    <product> 
     <id>19</id> 
     <name>daisy</name> 
     <manufacturer>79</manufacturer> 
     <description>t-shirt</description> 
     <sizes/> 
     <price>33.33</price> 
     <special>24.17</special> 
     <category_id>42</category_id> 
     <category1>clothes</category1> 
     <category2>t-shirt</category2> 
     <category3>latest</category3> 
     <green>S:M</green> 
     <orange>L:M</orange> 
     <image1>http://www.xyz.com/userfiles/daisy_green.png</image1> 
     <image2>http://www.xyz.com/userfiles/daisy_orange.png</image2> 
    </product> 
</products> 
+0

完美,這正是我在輸出時所需要的,非常感謝 – user1798073

+0

請再說一次,如果顏色的名稱有兩個單詞,例如淺藍色,元素必須命名爲light_blue,因爲轉換時出錯。請問,如何避免這種情況? – user1798073

+0

這是直截了當的,使用'translate'函數用下劃線替換空格。如果你不能馬上解決問題,最好問一個全新的問題,因爲這個問題已經相當大了。謝謝! –