2012-11-14 83 views
-2

我必須生成XMl輸出。它應該顯示數組,如後所示。我無法以正確的方式渲染數組。需要幫助寫入常見的xsl

輸入XML:

<accounts> 
    <displayOrdinal>0</displayOrdinal> 
    <name>String</name> 
    <account> 
     <accountNumber>String</accountNumber> 
     <name>String</name> 
     <balance> 
      <balanceAmount>0.0</balanceAmount> 
     </balance> 
     <balance> 
      <balanceAmount>0.0</balanceAmount> 
     </balance> 
     <properties> 
      <displayOrdinal>0</displayOrdinal> 
     </properties> 
     <properties> 
      <displayOrdinal>0</displayOrdinal> 
     </properties> 
     <usage> 
      <type>String</type> 
     </usage> 
     <usage> 
      <type>String</type> 
     </usage> 
    </account> 
    <account> 
     <accountNumber>String</accountNumber> 
     <name>String</name> 
     <balance> 
      <balanceAmount>0.0</balanceAmount> 
     </balance> 
     <balance> 
      <balanceAmount>0.0</balanceAmount> 
     </balance> 
     <properties> 
      <displayOrdinal>0</displayOrdinal> 
     </properties> 
     <properties> 
      <displayOrdinal>0</displayOrdinal> 
     </properties> 
     <usage> 
      <type>String</type> 
     </usage> 
     <usage> 
      <type>String</type> 
     </usage> 
    </account> 
</accounts> 

我預期的輸出應該如下:

<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx"> 
    <json:object name="accounts"> 
     <json:string name="displayOrdinal">0</json:string> 
     <json:string name="name">String</json:string> 
     <json:array name="account"> 
      <json:object> 
       <json:string name="accountNumber">String</json:string> 
       <json:string name="name">String</json:string> 
       <json:array name="balance"> 
        <json:object> 
         <json:string name="balanceAmount">0.0</json:string> 
        </json:object> 
        <json:object> 
         <json:string name="balanceAmount">0.0</json:string> 
        </json:object> 
       </json:array> 
       <json:array name="properties"> 
        <json:object> 
         <json:string name="displayOrdinal">0</json:string> 
        </json:object> 
        <json:object> 
         <json:string name="displayOrdinal">0</json:string> 
        </json:object> 
       </json:array> 
       <json:array name="usage"> 
        <json:object> 
         <json:string name="type">String</json:string> 
        </json:object> 
        <json:object name="usage"> 
         <json:string name="type">String</json:string> 
        </json:object> 
       </json:array> 
      </json:object> 
      <json:object> 
       <json:string name="accountNumber">String</json:string> 
       <json:string name="name">String</json:string> 
       <json:object name="balance"> 
        <json:string name="balanceAmount">0.0</json:string> 
       </json:object> 
       <json:array name="balance"> 
        <json:object> 
         <json:string name="balanceAmount">0.0</json:string> 
        </json:object> 
        <json:object> 
         <json:string name="displayOrdinal">0</json:string> 
        </json:object> 
        <json:object> 
         <json:string name="displayOrdinal">0</json:string> 
        </json:object> 
       </json:array> 
       <json:array name="usage"> 
        <json:object> 
         <json:string name="type">String</json:string> 
        </json:object> 
        <json:object> 
         <json:string name="type">String</json:string> 
        </json:object> 
       </json:array> 
      </json:object> 
     </json:array> 
    </json:object> 
</json:object> 

,我使用的XSL是如下:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx"> 
    <xsl:output method="xml" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/> 
    <xsl:strip-space elements="*"/> 
    <!-- Array --> 
    <xsl:template match="*[*[2]][name(*[1])=name(*[2])]"> 
     <json:object name="{name()}"> 
      <json:array name="{name(*[1])}"> 
       <xsl:apply-templates/> 
      </json:array> 
     </json:object> 
    </xsl:template> 
    <!-- Array member --> 
    <xsl:template match="*[parent::*[ name(*[1])=name(*[2]) ]] | /"> 
     <json:object> 
      <xsl:apply-templates/> 
     </json:object> 
    </xsl:template> 
    <!-- Object --> 
    <xsl:template match="*"> 
     <xsl:choose> 
      <xsl:when test="text()"> 
       <json:string name="{name()}"> 
        <xsl:value-of select="."/> 
       </json:string> 
      </xsl:when> 
      <xsl:otherwise> 
       <json:object name="{name()}"> 
        <xsl:apply-templates/> 
       </json:object> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
    <!-- String --> 
    <xsl:template match="*[not(*)]"> 
     <xsl:choose> 
      <xsl:when test="not(boolean(text()))"> 
       <xsl:element name="json:null"> 
        <xsl:attribute name="name"><xsl:value-of select="name()"/></xsl:attribute> 
       </xsl:element> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:choose> 
        <xsl:when test="text()= 'false' or text()='true'"> 
         <xsl:element name="json:boolean"> 
          <xsl:attribute name="name"><xsl:value-of select="name()"/></xsl:attribute> 
          <xsl:value-of select="text()"/> 
         </xsl:element> 
        </xsl:when> 
        <xsl:otherwise> 
         <json:string name="{name()}"> 
          <xsl:if test="@*"> 
           <xsl:attribute name="{name(@*)}"><xsl:value-of select="@*"/></xsl:attribute> 
          </xsl:if> 
          <xsl:value-of select="."/> 
         </json:string> 
        </xsl:otherwise> 
       </xsl:choose> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 
+1

我可能被誤認了,但是這是你已經問過的問題的重複嗎? http://stackoverflow.com/questions/12931751/need-general-xslt-for-xml-to-jsonx – ABach

+0

我已經更新了那裏的問題,但沒有人回覆如此張貼.. – user1731504

+0

任何人都可以請幫助我 – user1731504

回答

0

我想你會爲此需要一些模板。首先,對於數組中的元素,你將需要匹配誰擁有不同的前置兄弟元素,但匹配的命名下面的兄弟姐妹(即它們是數組的第一個元素)

<xsl:template 
     match="* 
     [local-name() != local-name(preceding-sibling::*[1])] 
     [local-name() = local-name(following-sibling::*[1])]" priority="2"> 
    <json:array name="{local-name()}"> 
     <xsl:apply-templates select="self::*" mode="array" /> 
    </json:array> 
</xsl:template> 

優先級在這裏,因爲使用在最終的XSLT中,將會有兩個模板可能匹配相同的元素,並且需要首先選擇數組。

然後,您可以通過將元素作爲json對象輸出來處理數組中的元素,然後匹配下面的兄弟,但只有它具有名稱名稱。

<xsl:template match="*" mode="array"> 
    <json:object> 
     <xsl:apply-templates /> 
    </json:object> 
    <xsl:apply-templates select="following-sibling::*[1][local-name() = local-name(current())]" mode="array" /> 
</xsl:template> 

還有將需要一個模板來停止數組中的元素相匹配的獨立陣列處理,使得沒有得到輸出兩次。

<xsl:template match="*[local-name() = local-name(preceding-sibling::*[1])]" /> 

將是一個字符串元素,這是沒有子元素

<xsl:template match="*[not(*)]" priority="1"> 
    <json:string name="{local-name()}"> 
     <xsl:value-of select="." /> 
    </json:string>  
</xsl:template> 

最後一個匹配其他元素,這也只是作爲對象輸出要素所需要的其他模板。

<xsl:template match="*"> 
    <json:object name="{local-name()}"> 
     <xsl:apply-templates /> 
    </json:object>  
</xsl:template> 

以下是完整的XSLT

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

    <xsl:template match="/"> 
     <json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx"> 
     <xsl:apply-templates /> 
     </json:object> 
    </xsl:template> 

    <xsl:template match="*[local-name() != local-name(preceding-sibling::*[1])][local-name() = local-name(following-sibling::*[1])]" priority="2"> 
     <json:array name="{local-name()}"> 
     <xsl:apply-templates select="self::*" mode="array" /> 
     </json:array> 
    </xsl:template> 

    <xsl:template match="*" mode="array"> 
     <json:object> 
     <xsl:apply-templates /> 
     </json:object> 
     <xsl:apply-templates select="following-sibling::*[1][local-name() = local-name(current())]" mode="array" /> 
    </xsl:template> 

    <xsl:template match="*[local-name() = local-name(preceding-sibling::*[1])]" /> 

    <xsl:template match="*[not(*)]" priority="1"> 
     <json:string name="{local-name()}"> 
     <xsl:value-of select="." /> 
     </json:string>  
    </xsl:template> 

    <xsl:template match="*"> 
     <json:object name="{local-name()}"> 
     <xsl:apply-templates /> 
     </json:object>  
    </xsl:template> 

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

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

<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx"> 
    <json:object name="accounts"> 
     <json:string name="displayOrdinal">0</json:string> 
     <json:string name="name">String</json:string> 
     <json:array name="account"> 
     <json:object> 
      <json:string name="accountNumber">String</json:string> 
      <json:string name="name">String</json:string> 
      <json:array name="balance"> 
       <json:object> 
        <json:string name="balanceAmount">0.0</json:string> 
       </json:object> 
       <json:object> 
        <json:string name="balanceAmount">0.0</json:string> 
       </json:object> 
      </json:array> 
      <json:array name="properties"> 
       <json:object> 
        <json:string name="displayOrdinal">0</json:string> 
       </json:object> 
       <json:object> 
        <json:string name="displayOrdinal">0</json:string> 
       </json:object> 
      </json:array> 
      <json:array name="usage"> 
       <json:object> 
        <json:string name="type">String</json:string> 
       </json:object> 
       <json:object> 
        <json:string name="type">String</json:string> 
       </json:object> 
      </json:array> 
     </json:object> 
     <json:object> 
      <json:string name="accountNumber">String</json:string> 
      <json:string name="name">String</json:string> 
      <json:array name="balance"> 
       <json:object> 
        <json:string name="balanceAmount">0.0</json:string> 
       </json:object> 
       <json:object> 
        <json:string name="balanceAmount">0.0</json:string> 
       </json:object> 
      </json:array> 
      <json:array name="properties"> 
       <json:object> 
        <json:string name="displayOrdinal">0</json:string> 
       </json:object> 
       <json:object> 
        <json:string name="displayOrdinal">0</json:string> 
       </json:object> 
      </json:array> 
      <json:array name="usage"> 
       <json:object> 
        <json:string name="type">String</json:string> 
       </json:object> 
       <json:object> 
        <json:string name="type">String</json:string> 
       </json:object> 
      </json:array> 
     </json:object> 
     </json:array> 
    </json:object> 
</json:object> 
+0

OP的輸出列表與你在第37和38行的輸出列表有所不同。在這個階段,我不能說OP是否發生錯誤,或者你的解決方案不安靜。 –

+0

不要流汗。我仔細檢查了一下,錯誤在於OP,而不是你的列表。 –

0

恭喜添作第一個正確的解決方案。

我的解決方案並不是更好,但我將其作爲一個感興趣的問題呈現。它產生與Tim相同的輸出,另外我還包含OP原始解決方案嘗試所建議的null和布爾類型。

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" 
    exclude-result-prefixes="xsl xs"> 
<xsl:output indent="yes" encoding="UTF-8" omit-xml-declaration="yes" /> 
<xsl:strip-space elements="*" /> 

<xsl:template match="/" name="nameless-object"> 
    <json:object> 
    <xsl:apply-templates />  
    </json:object> 
</xsl:template> 

<!-- Array --> 
<xsl:template match="* 
    [  following-sibling::*[1][name()=name(preceding-sibling::*[1])] ] 
    [not(preceding-sibling::*[1][name()=name(following-sibling::*[1])])]"> 
    <xsl:variable name="array-name" select="name()" /> 
    <xsl:variable name="followers" select=" 
    (.|following-sibling::*)[name()=$array-name]" /> 
    <xsl:variable name="stop" select=" 
    (following-sibling::*[name()!=$array-name][1] | 
     ../*[last()])[1]" /> 
    <xsl:variable name="preceders" select=" 
    ($stop| $stop/preceding-sibling::*)[name()=$array-name]" /> 
    <xsl:variable name="members" select=" 
     $preceders[count(.|$followers)=count($followers)]" /> 
    <json:array name="{$array-name}"> 
    <xsl:for-each select="$members"> 
     <xsl:call-template name="nameless-object" /> 
    </xsl:for-each> 
    </json:array> 
</xsl:template> 

<xsl:template match="* 
    [preceding-sibling::*[1][name()=name(following-sibling::*[1])] ]" /> 

<!-- Object --> 
<xsl:template match="*"> 
    <json:object name="{name()}"> 
    <xsl:apply-templates /> 
    </json:object> 
</xsl:template> 

<!-- String --> 
<xsl:template match="*[not(*)]"> 
    <json:string name="{name()}"> 
    <xsl:value-of select="." /> 
    </json:string> 
</xsl:template> 

<!-- Null --> 
<xsl:template match="*[not(*)][.='']"> 
    <json:null name="{name()}" /> 
</xsl:template> 

<!-- Boolean --> 
<xsl:template match="*[not(*)][.='true' or .='false']"> 
    <json:boolean name="{name()}"> 
    <xsl:value-of select="." /> 
    </json:boolean> 
</xsl:template> 

</xsl:stylesheet>