<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>
答案 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&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。