2017-02-22 75 views
1

我是XSLT新手,我需要使用xslt將xml文件轉換爲另一個xml文件。初學XML到XML動態轉換使用xslt

輸入文件是如下:

<root type="object"> 
    <items type="array"> 
     <item type="object"> 
      <original_file_name type="string">filename-m.mp3</original_file_name> 
      <description type="string">some description text</description> 
      <created_at type="string">2017-02-20T20:52:52Z</created_at> 
      <metadata type="object"> 
       <guest type="string">guestname here</guest> 
       <webInfo type="string">http://abc</webInfo> 
       <title type="string">title text testing</title> 
       <airDate type="string">2017-02-21</airDate> 
      </metadata> 
      <status type="string">live</status> 
      <asset_type type="string">video</asset_type> 
      <player_id type="string">391e099a718f4a62b44c78f97f85ecde</player_id> 
      <name type="string">title</name> 
     </item> 
     <item> 
     ..... 
     </item> 
    </items> 
</root> 

需要上面的XML變換,以下面的格式:

<?xml version="1.0" encoding="utf-8"?> 
<assets> 
    <item> 
     <original_file_name>filename-m.mp3</original_file_name> 
     <description>some description text</description> 
     <created_at>2017-02-20T20:52:52Z</created_at> 
     <guest>guestname here</guest> 
     <webInfo>http://abc</webInfo> 
     <title>title text testing</title> 
     <airDate>2017-02-21</airDate>  
     <status>live</status> 
     <asset_type>video</asset_type> 
     <player_id>391e099a718f4a62b44c78f97f85ecde</player_id> 
     <name>title</name> 
    </item> 
    <item> 
    ..... 
    </item> 
</assets> 

變換規則如下: 1)更換<root><items>...</items></root><assets>...</assets> 2)刪除所有屬性 3)刪除元數據標籤,並將元數據的子節點帶到item標籤的子節點。 4)元數據標籤的子節點是動態的,即子節點的數量和子節點的名稱可能會有所不同。

我能夠解決前兩點..第三和第四點的需求解決方案。 下面是我的代碼:

<?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" indent="yes" /> 
    <xsl:template match="/"> 
    <assets> 
     <xsl:for-each select="root/items/item"> 
      <item> 
       <original_file_name> 
       <xsl:value-of select="original_file_name"/> 
       </original_file_name> 
       <description> 
       <xsl:value-of select="description"/> 
       </description>    
      </item> 
     </xsl:for-each>  
    </assets> 
    </xsl:template> 
</xsl:stylesheet> 

非常感謝您立即作出反應,你派做工精細但對我來說,當我們有下面的線,它拋出一個錯誤代碼。當這行被刪除時,它工作正常。對於此行<xsl:strip-space elements="*" />我收到以下錯誤無法從已經加載的輸入文檔中去除空白區域。改爲將輸入文檔作爲XmlReader提供。

我還有一個疑問,做什麼,如果我們希望有一些子節點不是所有的子節點(選擇性)例如:

<root type="object"> 
    <items type="array"> 
     <item type="object"> 
      <elem1></elem1> 
      <elem2></elem2> 
      <elem3></elem3> 
      <elem4></elem4> 
      <elem5></elem5> 
      <elem6></elem6> 
      <elem7></elem7> 
     </item> 
    </items> 
</root> 

輸出應該如下:

<assets> 
    <item> 
     <elem1></elem1> 
     <elem3></elem3> 
     <elem6></elem6> 
     <elem7></elem7> 
    </item> 
</assets> 

回答

2

在類似這樣的問題,它幾乎總是最好先與identity template

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

這將複製所有節點和元素,因此您只需要擔心爲需要更改的內容編寫模板。

話雖如此,你需要刪除屬性,所以你實際上需要在這裏改變標識模板,以消除屬性@*的匹配,並將其移動到一個單獨的模板。

<xsl:template match="@*" /> 

要刪除metadata標籤,但保持它的孩子,添加一個模板,像這樣

<xsl:template match="metadata"> 
    <xsl:apply-templates select="node()"/> 
</xsl:template> 

其他唯一的改變是更換您的xsl:for-eachxsl:apply-templates而不是讓其他模板做他們的工作。

試試這個XSLT

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

    <xsl:strip-space elements="*" /> 

    <xsl:template match="/"> 
     <assets> 
      <xsl:apply-templates select="root/items/item" />  
     </assets> 
    </xsl:template> 

    <xsl:template match="metadata"> 
     <xsl:apply-templates select="node()"/> 
    </xsl:template> 

    <xsl:template match="@*" /> 

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

瞭解如何使用模板匹配和應用模板:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 

    <xsl:strip-space elements="*"/> 
    <xsl:output indent="yes"/> 

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

    <xsl:template match="root"> 
     <assets> 
      <xsl:apply-templates/> 
     </assets> 
    </xsl:template> 

    <xsl:template match="items | metadata"> 
     <xsl:apply-templates/> 
    </xsl:template> 
</xsl:transform> 

在線http://xsltransform.net/bwdwsK

+0

非常感謝您的回覆。 –