使用xslt请求Json转换

时间:2015-10-23 14:25:53

标签: xslt

    <html>    
Hi,
I have a sample json in this format:

{
  "d": {
    "results": [      
      {        
        "TYPE_ID": "20",
        "QUESTION_ID": "41333",
        "RESPONSE_TYPE": "Checkboxes",
        "QUESTIONVAL": "xssdsdd",
        "RESPONSE": "Yes",
        "RESPONSE_ORDER": "1"        
      }, 
      {        
        "TYPE_ID": "21",
        "QUESTION_ID": "417",
        "RESPONSE_TYPE": "Radio buttons",
        "QUESTIONVAL": "abc",
        "RESPONSE": "Yes,No",
        "RESPONSE_ORDER": "1,2"       
      }
    ]
  }
}

我想从RESPONSE和RESPONSE_ORDER标记中提取逗号分隔值,这样我就可以在输出JSON中清楚地设置它们。     基本上,我的输出应该是使用xslt转换的类似的东西。

{
    "results": [      
      {        
        "TYPE_ID": "20",
        "QUESTION_ID": "41333",
        "RESPONSE_TYPE": "Checkboxes",
        "QUESTIONVAL": "xssdsdd",
        Response&Order: [
            {
            "RESPONSE": "Yes",
            "RESPONSE_ORDER": "1"
            }
        ]               
      }, 
      {        
        "TYPE_ID": "21",
        "QUESTION_ID": "417",
        "RESPONSE_TYPE": "Radio buttons",
        "QUESTIONVAL": "abc",
        Response&Order: [
            {
            "RESPONSE": "Yes",
            "RESPONSE_ORDER": "1"
            },
            {
            "RESPONSE": "No",
            "RESPONSE_ORDER": "2"
            }
        ]             
      }
    ]
}

How can I split the values to generate this kind of output?

   </html>

1 个答案:

答案 0 :(得分:1)

XSLT在版本3.0之前不支持JSON。在Saxon 9.6(PE版及更高版本)中有一些支持。基本上,您必须将JSON转换为XML,转换它,然后再转换回来。 (理论上,XSLT 3.0允许您直接转换JSON,但根据我的经验,通过XML更容易实现。主要是,我认为,因为XML的数据模型允许您导航到兄弟姐妹和祖先,以及数据模型对于JSON没有。这在我的解决方案中有说明。

以下样式表完成了Saxon 9.6的工作:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:j="http://www.w3.org/2013/XSL/json"
    exclude-result-prefixes="xs"
    expand-text="yes"
    version="3.0">

    <xsl:variable name="input" expand-text="no">
        {"d": {"results": [
        {
        "TYPE_ID": "20",
        "QUESTION_ID": "41333",
        "RESPONSE_TYPE": "Checkboxes",
        "QUESTIONVAL": "xssdsdd",
        "RESPONSE": "Yes",
        "RESPONSE_ORDER": "1"
        },
        {
        "TYPE_ID": "21",
        "QUESTION_ID": "417",
        "RESPONSE_TYPE": "Radio buttons",
        "QUESTIONVAL": "abc",
        "RESPONSE": "Yes,No",
        "RESPONSE_ORDER": "1,2"
        }
        ]}}
    </xsl:variable>

    <xsl:output method="text" indent="yes"/>

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:template name="main">
        <xsl:variable name="inputAsXml" select="json-to-xml($input)"/>
        <xsl:variable name="outputAsXml">
                <xsl:apply-templates select="$inputAsXml"/>          
        </xsl:variable>
        <xsl:value-of select="xml-to-json($outputAsXml, map{'indent':true()})"/>
    </xsl:template>

    <xsl:template match="*[@key='d']">
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="*[@key='RESPONSE_ORDER']"/>

    <xsl:template match="*[@key='RESPONSE']">
            <xsl:variable name="response" select="tokenize(., ',')"/>
            <xsl:variable name="responseOrder" select="tokenize(../*[@key='RESPONSE_ORDER'], ',')"/>
            <j:array key="Response&amp;Order">
                <xsl:for-each select="1 to count($response)">
                    <xsl:variable name="i" select="."/>
                    <j:map>
                       <j:string key="RESPONSE">{$response[$i]}</j:string>
                       <j:string key="RESPONSE_ORDER">{$responseOrder[$i]}</j:string>
                    </j:map> 
                </xsl:for-each>
            </j:array>       
    </xsl:template>

</xsl:stylesheet>

产生的输出是:

  { "results" : 
    [ 
      { "TYPE_ID" : "20",
        "QUESTION_ID" : "41333",
        "RESPONSE_TYPE" : "Checkboxes",
        "QUESTIONVAL" : "xssdsdd",
        "Response&Order" : 
        [ 
          { "RESPONSE" : "Yes",
            "RESPONSE_ORDER" : "1" } ] },

      { "TYPE_ID" : "21",
        "QUESTION_ID" : "417",
        "RESPONSE_TYPE" : "Radio buttons",
        "QUESTIONVAL" : "abc",
        "Response&Order" : 
        [ 
          { "RESPONSE" : "Yes",
            "RESPONSE_ORDER" : "1" },

          { "RESPONSE" : "No",
            "RESPONSE_ORDER" : "2" } ] } ] }

这里使用的主要XSLT 3.0功能是json-to-xml()和xml-to-json()两个函数。要理解转换,您需要了解这些函数使用的JSON的XML表示,这在此处进行了解释:http://www.w3.org/TR/xslt-30/#json-to-xml-mapping

XSLT 3.0规范仍然是草案,在最终发布之前可能会有更改。使这一工作与当前(未发表的)工作草案相关的唯一变化是命名空间的改变;而不是http://www.w3.org/2013/XSL/json,请使用http://www.w3.org/2005/xpath-functions