2011-10-05 169 views
2

我嘗試過不同的方式將此信息處理爲xml,沒有任何工作。如何將純文本轉換爲xsl

請幫忙

我在一個標籤內有多行。我必須將它們轉換爲適當的xml文檔。

這裏是文本/字符串

<params> 
     userdata_token=>'abd' 
     userdata_time=>'12/09/2011' 
     user_message_address_city=>'Manchester|Harrow|' 
     user_message_address_postcode=>'M20 7LD||HA0 4BN' 
     user_message_address_addressee=>'|Pete|' 
    </params> 

爲XML格式像

<params> 
    <userdata> 
     <token>abd</temp> 
     <time>12/09/2011</time> 
    </userdata> 
    <user> 
     <message> 
     <address> 
      <city>Manchester</city> 
      <postcode>M20 7LD</postcode> 
      <addressee></addressee> 
     </address>  
     <address> 
      <city>Harrow</city> 
      <postcode></postcode> 
      <addressee>Pete</addressee> 
     </address> 
     <address> 
      <city></city> 
      <postcode>HA0 4BN</postcode> 
      <addressee></addressee> 
     </address> 
     </message> 
     <user>  
    </params> 

請能有人在劈裂的字符串的分層元素和相應的值幫助,我期待在做這個XSL和Java,輸出格式良好的XML。我沒有輸出的xsd,所以我不能使用綁定模式。

回答

2

這實際上在XSLT 2.0中非常方便。

對於一個快速演示的目的(未完全完成,拋光,但給你這種處理與XSLT 2.0的想法),我剛剛在幾分鐘內拿出這樣的:

<xsl:stylesheet version="2.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:xs="http://www.w3.org/2001/XMLSchema" 
     xmlns:my="my:my"> 
     <xsl:output omit-xml-declaration="yes" indent="yes"/> 

     <xsl:variable name="vLines" select= 
      "tokenize(string(/*), '\s*&#xA;\s*')[.]"/> 

    <xsl:template match="/"> 
     <xsl:sequence select="my:ProcessLines($vLines)"/> 
      <xsl:text>&#xA;</xsl:text> 
    </xsl:template> 

    <xsl:function name="my:ProcessLines" as="element()*"> 
     <xsl:param name="pLines" as="xs:string*"/> 

     <xsl:for-each select="$pLines"> 
     <xsl:sequence select="my:ProcessLine(.)"/> 
     </xsl:for-each> 
    </xsl:function> 

    <xsl:function name="my:ProcessLine" as="element()*"> 
     <xsl:param name="pLine" as="xs:string*"/> 

     <xsl:variable name="vSides" select="tokenize($pLine, '=>')"/> 

     <xsl:variable name="vLHS" select="$vSides[1]"/> 
     <xsl:variable name="vRHS" select= 
      "substring($vSides[2],2, string-length($vSides[2])-2)"/> 

     <xsl:variable name="vGendElement" select= 
      "my:MakeElement(tokenize($vLHS, '_'))"/> 

     <xsl:sequence select="my:ImplantValues($vGendElement, $vRHS)"/> 
    </xsl:function> 

    <xsl:function name="my:MakeElement" > 
     <xsl:param name="pElemNames" as="xs:string*"/> 

     <xsl:if test="not(empty($pElemNames))"> 
     <xsl:element name="{$pElemNames[1]}"> 
      <xsl:sequence select= 
      "my:MakeElement($pElemNames[position() > 1])"/> 
     </xsl:element> 
     </xsl:if> 
    </xsl:function> 

    <xsl:function name="my:ImplantValues" as="element()*"> 
     <xsl:param name="pTree" as="element()"/> 
     <xsl:param name="pValues" as="xs:string"/> 

     <xsl:variable name="vValues" select="tokenize($pValues, '\|')[.]"/> 

     <xsl:for-each select="$vValues[string-length(normalize-space()) > 0]"> 
     <xsl:apply-templates select="$pTree"> 
      <xsl:with-param name="pValue" select="."/> 
     </xsl:apply-templates> 
     </xsl:for-each> 
    </xsl:function> 

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

    <xsl:template match="*[not(*)]"> 
     <xsl:param name="pValue"/> 

     <xsl:copy> 
     <xsl:copy-of select="@*"/> 
     <xsl:copy-of select="$pValue"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

當這個變換所提供的XML文檔施加(它也可以簡單地使用unparsed-text()函數從文件中讀取輸入):

<params> 
    userdata_token=>'abd' 
    userdata_time=>'12/09/2011' 
    user_message_address_city=>'Manchester|Harrow|' 
    user_message_address_postcode=>'M20 7LD||HA0 4BN' 
    user_message_address_addressee=>'|Pete|' 
</params> 

結果是

<userdata> 
    <token>abd</token> 
</userdata> 
<userdata> 
    <time>12/09/2011</time> 
</userdata> 
<user> 
    <message> 
     <address> 
     <city>Manchester</city> 
     </address> 
    </message> 
</user> 
<user> 
    <message> 
     <address> 
     <city>Harrow</city> 
     </address> 
    </message> 
</user> 
<user> 
    <message> 
     <address> 
     <postcode>M20 7LD</postcode> 
     </address> 
    </message> 
</user> 
<user> 
    <message> 
     <address> 
     <postcode>HA0 4BN</postcode> 
     </address> 
    </message> 
</user> 
<user> 
    <message> 
     <address> 
     <addressee>Pete</addressee> 
     </address> 
    </message> 
</user> 

要完成這一點,只需要增加一些分組 - 我準備去上班,所以這可能在今天晚些時候進行。 :)

+0

+1對於一個很好的答案。 @Sujith - 這是另一個Dimitre Novatchev答案的鏈接,可能有所幫助。 http://stackoverflow.com/questions/3233120/creating-new-elements-through-text-processing-in-xslt –

+0

@DevNull:不客氣。 –

+0

謝謝Dimitre我會嘗試適應這個解決方案。 – Sujith

0

XSL並不關心你的輸出是什麼;輸入必須是格式良好的XML。在這種情況下,您的XML 格式正確,但文本節點包含一些需要理解的格式化信息。我的建議是不要過分使用XSL。使用正則表達式甚至StringTokenizer進行直分析將提取您的數據。從那裏可以很容易地編寫結果文檔。

1

在XSLT 2中完全可能。看一下未解析的文本函數,可以使用它來讀取文件的內容。您可以先調用unparsed-text-available以確保文件可訪問,所以如果不是,XSL轉換不會失敗。

然後可以將字符串拆分爲行和名稱/值對。查看如何執行此操作的tokenize,string-before和string-after函數。最後,使用< xsl:element >創建您想要的輸出結構。