2011-05-23 47 views
2

我有一個XML,看起來像這樣轉換XML到合適的文本

<person> 
    <name> 
     <name-first>foo</name-first> 
     <name-last>bar</name-last> 
    </name> 
    <age>20</age> 
    <city>nowhere</city> 
</person> 

我想這個轉換成

person: 
    { 
    name: { 
      name-first:'foo', 
      name-last:'bar' 
      }, 
    age:'20', 
    city:'nowhere' 
    } 

在此先感謝。

+0

許多編程語言都有一個XML庫,因此您可以輕鬆創建一個快速程序來爲您執行此操作。如果您最喜歡的語言不包含XML庫,那麼您也可以使用字符串操作來完成此操作。 – 2011-05-23 10:48:25

+0

@ingo vals - 謝謝你的迴應,@代碼 - 我已經試過了下面的代碼:<?xml version =「1.0」encoding =「ISO-8859-1」?> \t \t <的xsl:for-每個選擇= 「*」> \t { \t \t的:\t的 \t} \t的 \t ,但我沒有得到我想要的東西。請幫忙。 – novein 2011-05-23 10:55:56

+0

好問題,+1。查看我的答案,獲取完整,簡短的XSLT解決方案。 – 2011-05-23 13:19:00

回答

1

下面是一個簡單的轉換 - 一開始

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pIndents" select="' '"/> 

<xsl:template match="*[*]"> 
    <xsl:param name="pcurrentIndents" select="''"/> 
    <xsl:value-of select="concat($pcurrentIndents, name(), ':')"/> 
    <xsl:value-of select="concat('&#xA;',$pcurrentIndents, '{')"/> 
     <xsl:apply-templates> 
     <xsl:with-param name="pcurrentIndents" select= 
     "concat($pcurrentIndents, $pIndents)"/> 
     </xsl:apply-templates> 
    <xsl:value-of select="concat('&#xA;',$pcurrentIndents, '}')"/> 
</xsl:template> 

<xsl:template match="*[not(*)]"> 
    <xsl:param name="pcurrentIndents" select="''"/> 
    <xsl:text>&#xA;</xsl:text> 
    <xsl:value-of select="concat($pcurrentIndents, name(), ':')"/> 
    <xsl:apply-templates/> 
</xsl:template> 
</xsl:stylesheet> 

當這種轉變是在所提供的XML文檔應用:

<person> 
    <name> 
     <name-first>foo</name-first> 
     <name-last>bar</name-last> 
    </name> 
    <age>20</age> 
    <city>nowhere</city> 
</person> 

想要的,正確的結果產生

person: 
{ name: 
    { 
    name-first:foo 
    name-last:bar 
    } 
    age:20 
    city:nowhere 
} 

說明

  1. 有匹配的元素有兩個模板。

  2. 模板匹配*[*]匹配具有子元素的元素。它使用name()函數,:字符,NL字符,當前縮進(空格數)和{字符生成當前匹配元素的名稱。然後,將模板應用於當前匹配元素的子節點,參數$pcurrentIndents傳遞當前縮進,增加空間字符的預增量(如全局參數$pIndents中指定的那樣)。最後,在新行上使用當前縮進,最後的花括號是putput。

  3. 匹配*[not(*)](沒有任何元素作爲子元素的元素)的模板類似但更簡單。它輸出當前縮進處匹配元素的名稱和:字符。在這裏應用模板爲非元素節點調用XSLT內置模板 - 在這種情況下,將選擇與文本節點匹配的內置模板,並將文本節點複製到輸出。

+0

感謝這樣一個美好的迴應。你的代碼工作得很好,但是,我仍然需要更多的修改,比如在行尾添加逗號''。如果你能分享/解釋我的代碼是如何工作的,我會很高興,這將是一個很好的學習/理解XML。 – novein 2011-05-23 13:30:22

+0

@novein:不客氣。我添加了一個解釋。 – 2011-05-23 13:46:54

+0

感謝您的解釋,我會嘗試修改它以符合我的要求。 – novein 2011-05-23 14:19:19

1

這裏是一個應該給你如何將XML轉換爲所需的輸出一些想法的例子XSL模板:

<xsl:template match="person"> 
person: 
    { 
    name: { 
      name-first:<xsl:value-of select="name/name-first"/>, 
      name-last:<xsl:value-of select="name/name-last"/> 
      }, 
    age:<xsl:value-of select="age"/>, 
    city:<xsl:value-of select="city"/> 
    } 
</xsl:template> 
+0

是的,那是真的。但是,我想要一個更通用的方式來做到這一點,而不必明確指定節點名稱。我的意思是,如果我在XML中添加更多的節點,那麼XSL仍然應該給出輸出而不做任何修改。無論如何,謝謝你的迴應。 – novein 2011-05-23 11:16:11