使用 XSLT 将单个 xml 元素转换为 Json 数组的问题
problems to convert single xml element to Json Array using XSLT
我正在使用下面的通用 xslt 将 xml 转换为 json ,但是第一个数组属性下缺少一些值。期望是使用 make ns1:Value 作为 JSON 数组,即使我们得到单个 xml 元素
这里我提到了示例 xml 和 json 消息。
XSLT 代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">{
<xsl:apply-templates select="*"/>}
</xsl:template>
<!-- Object or Element Property-->
<xsl:template match="*">
"<xsl:value-of select="name()"/>" : <xsl:call-template name="Properties"/>
</xsl:template>
<!-- Array Element -->
<xsl:template match="*" mode="ArrayElement">
<xsl:call-template name="Properties"/>
</xsl:template>
<!-- Object Properties -->
<xsl:template name="Properties">
<xsl:variable name="childName" select="name(*[1])"/>
<xsl:choose>
<xsl:when test="not(*|@*)">"<xsl:value-of select="."/>"</xsl:when>
<xsl:when test="$childName = 'ns1:Value' or count(*[name()=$childName]) > 1">{ "<xsl:value-of select="$childName"/>" :[<xsl:apply-templates select="*" mode="ArrayElement"/>] }</xsl:when>
<xsl:otherwise>{
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="*"/>
}</xsl:otherwise>
</xsl:choose>
<xsl:if test="following-sibling::*">,</xsl:if>
</xsl:template>
<!-- Attribute Property -->
<xsl:template match="@*">"<xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>",
</xsl:template>
</xsl:stylesheet>
样本XML:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="urn://opten/soap/cegtar/unique">
<SOAP-ENV:Body>
<ns1:abcResponse>
<ns1:abc id="10485824">
<ns1:Rovatok/>
<ns1:ScoringAdatok>
<ns1:XData tipus="11" megnevezes="APEH hátralék (rendezetlen)">
<ns1:Value num="1" subtype="xbool">false</ns1:Value>
</ns1:XData>
<ns1:XData tipus="13" megnevezes="Egyéb VH (rendezetlen)">
<ns1:Value num="1" subtype="xbool">false</ns1:Value>
</ns1:XData>
<ns1:XData tipus="33" megnevezes="Opten kockázati besorolás">
<ns1:Value num="1" subtype="xstring">A</ns1:Value>
</ns1:XData>
<ns1:XData tipus="46" megnevezes="Cég-állapot (APAFI helyett)">
<ns1:Value num="1" subtype="xdate">0000-00-00</ns1:Value>
<ns1:Value num="2" subtype="xnum">0</ns1:Value>
</ns1:XData>
<ns1:XData tipus="68" megnevezes="Kockázati index szám">
<ns1:Value num="1" subtype="xnum">9</ns1:Value>
</ns1:XData>
<ns1:XData tipus="69" megnevezes="A cég keresdelmi hitelkerete">
<ns1:Value num="1" subtype="xnum">250000</ns1:Value>
<ns1:Value num="2" subtype="xnum">0</ns1:Value>
</ns1:XData>
<ns1:XData tipus="77" megnevezes="Adószám állapot">
<ns1:Value num="1" subtype="xnum">0</ns1:Value>
<ns1:Value num="2" subtype="xstring">Érvényes az adószám</ns1:Value>
</ns1:XData>
</ns1:ScoringAdatok>
<ns1:MerlegAdatok/>
</ns1:abc>
</ns1:abcResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
JSON 响应中缺少属性值,即“tipus and megnevezes”值:
预期 JSON 响应:
{
"SOAP-ENV:Envelope": {
"SOAP-ENV:Body": {
"ns1:MultiInfoResponse": {
"ns1:MultiInfo": {
"id": "10485824",
"ns1:Rovatok": "",
"ns1:ScoringAdatok": {
"ns1:XData": [{
"tipus": "11",
"megnevezes": "APEH hátralék (rendezetlen)",
"ns1:Value": [{
"num": "1",
"subtype": "xbool",
"text": "false"
}]
}, {
"tipus": "13",
"megnevezes": "Egyéb VH (rendezetlen)",
"ns1:Value": [{
"num": "1",
"subtype": "xbool",
"text": "false"
}]
}, {
"tipus": "33",
"megnevezes": "Opten kockázati besorolás",
"ns1:Value": [{
"num": "1",
"subtype": "xstring",
"text": "A"
}]
}, {
"tipus": "46",
"megnevezes": "Cég-állapot (APAFI helyett)",
"ns1:Value": [{
"num": "1",
"subtype": "xdate",
"text": "0000-00-00"
}, {
"num": "2",
"subtype": "xnum",
"text": "0"
}]
}, {
"tipus": "68",
"megnevezes": "Kockázati index szám",
"ns1:Value": [{
"num": "1",
"subtype": "xnum",
"text": "9"
}]
}, {
"tipus": "69",
"megnevezes": "A cég keresdelmi hitelkerete",
"ns1:Value": [{
"num": "1",
"subtype": "xnum",
"text": "250000"
}, {
"num": "2",
"subtype": "xnum",
"text": "0"
}]
}, {
"tipus": "77",
"megnevezes": "Adószám állapot",
"ns1:Value": [{
"num": "1",
"subtype": "xnum",
"text": "0"
}, {
"num": "2",
"subtype": "xstring",
"text": "Érvényes az adószám"
}]
}]
},
"ns1:MerlegAdatok": ""
}
}
}
}
}
编辑
几年前我用 xslt 1.0 做了一个 xml2json。
这也处理转义特价 json-chars 和其他奖金。
我根据您的需要做了一些调整。享受:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8" media-type="application/json" />
<xsl:strip-space elements="*"/>
<xsl:variable name="separator"><xsl:text>,</xsl:text></xsl:variable>
<xsl:template match="/">{
<xsl:apply-templates select="*" mode="obj-key"/>}
</xsl:template>
<xsl:template match="*[not(* or @* )]" mode="obj-key">
<xsl:variable name="name" select="name()"/>
<xsl:if test="not(preceding-sibling::*[name()=$name])">
<xsl:text>"</xsl:text>
<xsl:call-template name="nameWithOptinalMinusToCamelcase"/>
<xsl:text>": "</xsl:text>
<xsl:value-of select="."/>
<xsl:text>"</xsl:text>
<xsl:if test="following-sibling::*[not(name()=$name)]">
<!-- If other elements with different name use comma -->
<xsl:value-of select="$separator"/>
</xsl:if>
</xsl:if>
</xsl:template>
<!-- Recursieve element node -->
<xsl:template match="*" mode="obj-key">
<xsl:variable name="name" select="name()"/>
<xsl:variable name="treatAsArray" select="count(parent::*/*[name()=$name]) > 1 or $name='ns1:Value'"/>
<xsl:if test="not(preceding-sibling::*[name()=$name])">
<xsl:text>"</xsl:text>
<xsl:call-template name="nameWithOptinalMinusToCamelcase"/>
<xsl:text>": </xsl:text>
<xsl:choose>
<xsl:when test="$treatAsArray">
<xsl:text>[</xsl:text>
<xsl:apply-templates select="." mode="obj-content"/>
<xsl:text>]</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="." mode="obj-content"/>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="following-sibling::*[not(name()=$name)]">
<!-- If other elements with different name use comma -->
<xsl:value-of select="$separator"/>
</xsl:if>
</xsl:if>
</xsl:template>
<xsl:template match="*[* or @*]" mode="obj-content">
<xsl:variable name="is-child-element-model" select="count(*) > 0"/>
<xsl:variable name="is-text-node-model" select="count(*)=0 and normalize-space(.) !=''"/>
<xsl:text>{</xsl:text>
<xsl:apply-templates select="@*" mode="attributes"/>
<xsl:if test="@* and ($is-child-element-model or $is-text-node-model)">
<xsl:value-of select="$separator"/>
</xsl:if>
<xsl:choose>
<xsl:when test="$is-text-node-model">
<xsl:apply-templates select="text()" mode="content-text"/>
</xsl:when>
<xsl:when test="$is-child-element-model">
<xsl:apply-templates select="*" mode="obj-key"/>
</xsl:when>
</xsl:choose>
<xsl:text>}</xsl:text>
<xsl:apply-templates select="." mode="following-sibling"/>
</xsl:template>
<xsl:template mode="content" match="text()[ string-length(translate(.,'0123456789',''))=0
and string-length(normalize-space(.)) > 0
and (substring(.,1,1)!='0' or string-length(.)=1)]"
priority="2">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template mode="content" match="text()[translate(.,'TRUE','true')='true']" priority="2">true</xsl:template>
<xsl:template mode="content" match="text()[translate(.,'FALSE','false')='false']" priority="2">false</xsl:template>
<xsl:template mode="content-text" match="*[@* or *]/text()">
<xsl:text>"text": </xsl:text>
<xsl:apply-templates select="." mode="content"/>
</xsl:template>
<xsl:template match="*" mode="following-sibling">
<xsl:variable name="name" select="name()"/>
<xsl:if test="following-sibling::*[name()=$name]">
<!-- If there are other elements with same name use comma -->
<xsl:value-of select="$separator"/>
<xsl:apply-templates select="following-sibling::*[name()=$name][1]" mode="obj-content"/>
</xsl:if>
</xsl:template>
<xsl:template mode="content" match="text()">
<xsl:text>"</xsl:text>
<xsl:value-of select="."/>
<xsl:text>"</xsl:text>
</xsl:template>
<!--
|| Attributen met text dienen ge-escaped te worden
-->
<xsl:template match="@*" mode="attributes">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>": "</xsl:text>
<xsl:call-template name="escape-special-json-chars"/>
<xsl:text>"</xsl:text>
<xsl:if test="position() < last()">
<xsl:value-of select="$separator"/>
</xsl:if>
</xsl:template>
<xsl:template match="@*[translate(.,'FALSE','false')='false']" mode="attributes">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>": false</xsl:text>
<xsl:if test="position() < last()">
<xsl:value-of select="$separator"/>
</xsl:if>
</xsl:template>
<xsl:template match="@*[translate(.,'TRUE','true')='true']" mode="attributes">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>": true</xsl:text>
<xsl:if test="position() < last()">
<xsl:value-of select="$separator"/>
</xsl:if>
</xsl:template>
<xsl:template match="@*[string-length(translate(.,'0123456789',''))=0 and string-length(normalize-space(.)) > 0 and (substring(.,1,1)!='0' or string-length(.)=1)]" mode="attributes" >
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>": </xsl:text>
<xsl:value-of select="."/>
<xsl:if test="position() < last()">
<xsl:value-of select="$separator"/>
</xsl:if>
</xsl:template>
<xsl:variable name="escChr" select="'\'"/>
<xsl:variable name="dqt">"</xsl:variable>
<xsl:variable name="cr" select="' '"/>
<xsl:variable name="nl" select="' '"/>
<xsl:variable name="sls" select="'\'"/>
<xsl:variable name="tab" select="'	'"/>
<xsl:template name="escape-special-json-chars">
<xsl:variable name="textSlsEsc">
<xsl:call-template name="escapeString">
<xsl:with-param name="text" select="." />
<xsl:with-param name="escape" select="$sls"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="textCrEsc">
<xsl:call-template name="escapeString">
<xsl:with-param name="text" select="$textSlsEsc" />
<xsl:with-param name="escape" select="$cr"/>
<xsl:with-param name="with" select="'\r'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="textLfEsc">
<xsl:call-template name="escapeString">
<xsl:with-param name="text" select="$textCrEsc" />
<xsl:with-param name="escape" select="$nl"/>
<xsl:with-param name="with" select="'\n'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="textDqtEsc">
<xsl:call-template name="escapeString">
<xsl:with-param name="text" select="$textLfEsc" />
<xsl:with-param name="escape" select="$dqt"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="textTabEsc">
<xsl:call-template name="escapeString">
<xsl:with-param name="text" select="$textDqtEsc" />
<xsl:with-param name="escape" select="$tab"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$textTabEsc"/>
</xsl:template>
<xsl:template name="escapeString">
<xsl:param name="text"/>
<xsl:param name="escape"/>
<xsl:param name="with" select="concat($escChr,$escape)"/>
<xsl:param name="prevText" select="'ditWordtNooitGevonden'"/>
<xsl:choose>
<xsl:when test="contains($text,$escape)">
<xsl:variable name="testChar">
<xsl:choose>
<xsl:when test="$escape=$escChr">
<xsl:value-of select="substring(substring-after($text,$escape),1,1)"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="before" select="substring-before($text,$escape)"/>
<xsl:value-of select="substring($before, string-length($before))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="testCharIsEscapeChr" select="$testChar=$escChr"/>
<xsl:choose>
<xsl:when test="$testCharIsEscapeChr">
<!-- Karakter is al ge-escaped -->
<xsl:value-of select="substring-before($text,$with)"/>
<xsl:value-of select="$with"/>
<xsl:call-template name="escapeString">
<xsl:with-param name="text" select="substring-after($text,$with)"/>
<xsl:with-param name="escape" select="$escape"/>
<xsl:with-param name="with" select="$with"/>
<xsl:with-param name="prevText" select="$text"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-before($text,$escape)"/>
<xsl:value-of select="$with"/>
<xsl:call-template name="escapeString">
<xsl:with-param name="text" select="substring-after($text,$escape)"/>
<xsl:with-param name="escape" select="$escape"/>
<xsl:with-param name="with" select="$with"/>
<xsl:with-param name="prevText" select="$text"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'"/>
<!--
|| json properties can't have a minus sign
-->
<xsl:template name="nameWithOptinalMinusToCamelcase">
<xsl:param name="name" select="name()"/>
<xsl:choose>
<xsl:when test="contains($name,'-')">
<xsl:value-of select="substring-before($name,'-')"/>
<xsl:variable name="after" select="substring-after($name,'-')"/>
<xsl:value-of select="translate(substring($after,1,1), $lower, $upper)"/>
<xsl:call-template name="nameWithOptinalMinusToCamelcase">
<xsl:with-param name="name" select="substring($after,2)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
正在申请xml:
<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn://xyz/soap/cegtar/unique">
<SOAP-ENV:Body>
<ns1:abcResponse>
<ns1:abc id="12345">
<ns1:Rovatok/>
<ns1:ScoringAdatok>
<ns1:XData tipus="11" megnevezes="APEH hátralék (rendezetlen)">
<ns1:Value num="1" subtype="xbool">false</ns1:Value>
</ns1:XData>
<ns1:XData tipus="13" megnevezes="Egyéb VH (rendezetlen)">
<ns1:Value num="1" subtype="xbool">false</ns1:Value>
</ns1:XData>
<ns1:XData tipus="46" megnevezes="Cég-állapot (APAFI helyett)">
<ns1:Value num="1" subtype="xdate">0000-00-00</ns1:Value>
<ns1:Value num="2" subtype="xnum">0</ns1:Value>
</ns1:XData>
</ns1:ScoringAdatok>
</ns1:abc>
</ns1:abcResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
结果:
{
"SOAP-ENV:Envelope": {
"SOAP-ENV:Body": {
"ns1:abcResponse": {
"ns1:abc": {
"id": 12345,
"ns1:Rovatok": "",
"ns1:ScoringAdatok": {
"ns1:XData": [
{
"tipus": 11,
"megnevezes": "APEH hátralék (rendezetlen)",
"ns1:Value": [
{
"num": 1,
"subtype": "xbool",
"text": false
}
]
},
{
"tipus": 13,
"megnevezes": "Egyéb VH (rendezetlen)",
"ns1:Value": [
{
"num": 1,
"subtype": "xbool",
"text": false
}
]
},
{
"tipus": 46,
"megnevezes": "Cég-állapot (APAFI helyett)",
"ns1:Value": [
{
"num": 1,
"subtype": "xdate",
"text": "0000-00-00"
},
{
"num": 2,
"subtype": "xnum",
"text": 0
}
]
}
]
}
}
}
}
}
}
我正在使用下面的通用 xslt 将 xml 转换为 json ,但是第一个数组属性下缺少一些值。期望是使用 make ns1:Value 作为 JSON 数组,即使我们得到单个 xml 元素 这里我提到了示例 xml 和 json 消息。 XSLT 代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">{
<xsl:apply-templates select="*"/>}
</xsl:template>
<!-- Object or Element Property-->
<xsl:template match="*">
"<xsl:value-of select="name()"/>" : <xsl:call-template name="Properties"/>
</xsl:template>
<!-- Array Element -->
<xsl:template match="*" mode="ArrayElement">
<xsl:call-template name="Properties"/>
</xsl:template>
<!-- Object Properties -->
<xsl:template name="Properties">
<xsl:variable name="childName" select="name(*[1])"/>
<xsl:choose>
<xsl:when test="not(*|@*)">"<xsl:value-of select="."/>"</xsl:when>
<xsl:when test="$childName = 'ns1:Value' or count(*[name()=$childName]) > 1">{ "<xsl:value-of select="$childName"/>" :[<xsl:apply-templates select="*" mode="ArrayElement"/>] }</xsl:when>
<xsl:otherwise>{
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="*"/>
}</xsl:otherwise>
</xsl:choose>
<xsl:if test="following-sibling::*">,</xsl:if>
</xsl:template>
<!-- Attribute Property -->
<xsl:template match="@*">"<xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>",
</xsl:template>
</xsl:stylesheet>
样本XML:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="urn://opten/soap/cegtar/unique">
<SOAP-ENV:Body>
<ns1:abcResponse>
<ns1:abc id="10485824">
<ns1:Rovatok/>
<ns1:ScoringAdatok>
<ns1:XData tipus="11" megnevezes="APEH hátralék (rendezetlen)">
<ns1:Value num="1" subtype="xbool">false</ns1:Value>
</ns1:XData>
<ns1:XData tipus="13" megnevezes="Egyéb VH (rendezetlen)">
<ns1:Value num="1" subtype="xbool">false</ns1:Value>
</ns1:XData>
<ns1:XData tipus="33" megnevezes="Opten kockázati besorolás">
<ns1:Value num="1" subtype="xstring">A</ns1:Value>
</ns1:XData>
<ns1:XData tipus="46" megnevezes="Cég-állapot (APAFI helyett)">
<ns1:Value num="1" subtype="xdate">0000-00-00</ns1:Value>
<ns1:Value num="2" subtype="xnum">0</ns1:Value>
</ns1:XData>
<ns1:XData tipus="68" megnevezes="Kockázati index szám">
<ns1:Value num="1" subtype="xnum">9</ns1:Value>
</ns1:XData>
<ns1:XData tipus="69" megnevezes="A cég keresdelmi hitelkerete">
<ns1:Value num="1" subtype="xnum">250000</ns1:Value>
<ns1:Value num="2" subtype="xnum">0</ns1:Value>
</ns1:XData>
<ns1:XData tipus="77" megnevezes="Adószám állapot">
<ns1:Value num="1" subtype="xnum">0</ns1:Value>
<ns1:Value num="2" subtype="xstring">Érvényes az adószám</ns1:Value>
</ns1:XData>
</ns1:ScoringAdatok>
<ns1:MerlegAdatok/>
</ns1:abc>
</ns1:abcResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
JSON 响应中缺少属性值,即“tipus and megnevezes”值: 预期 JSON 响应:
{
"SOAP-ENV:Envelope": {
"SOAP-ENV:Body": {
"ns1:MultiInfoResponse": {
"ns1:MultiInfo": {
"id": "10485824",
"ns1:Rovatok": "",
"ns1:ScoringAdatok": {
"ns1:XData": [{
"tipus": "11",
"megnevezes": "APEH hátralék (rendezetlen)",
"ns1:Value": [{
"num": "1",
"subtype": "xbool",
"text": "false"
}]
}, {
"tipus": "13",
"megnevezes": "Egyéb VH (rendezetlen)",
"ns1:Value": [{
"num": "1",
"subtype": "xbool",
"text": "false"
}]
}, {
"tipus": "33",
"megnevezes": "Opten kockázati besorolás",
"ns1:Value": [{
"num": "1",
"subtype": "xstring",
"text": "A"
}]
}, {
"tipus": "46",
"megnevezes": "Cég-állapot (APAFI helyett)",
"ns1:Value": [{
"num": "1",
"subtype": "xdate",
"text": "0000-00-00"
}, {
"num": "2",
"subtype": "xnum",
"text": "0"
}]
}, {
"tipus": "68",
"megnevezes": "Kockázati index szám",
"ns1:Value": [{
"num": "1",
"subtype": "xnum",
"text": "9"
}]
}, {
"tipus": "69",
"megnevezes": "A cég keresdelmi hitelkerete",
"ns1:Value": [{
"num": "1",
"subtype": "xnum",
"text": "250000"
}, {
"num": "2",
"subtype": "xnum",
"text": "0"
}]
}, {
"tipus": "77",
"megnevezes": "Adószám állapot",
"ns1:Value": [{
"num": "1",
"subtype": "xnum",
"text": "0"
}, {
"num": "2",
"subtype": "xstring",
"text": "Érvényes az adószám"
}]
}]
},
"ns1:MerlegAdatok": ""
}
}
}
}
}
编辑
几年前我用 xslt 1.0 做了一个 xml2json。 这也处理转义特价 json-chars 和其他奖金。
我根据您的需要做了一些调整。享受:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8" media-type="application/json" />
<xsl:strip-space elements="*"/>
<xsl:variable name="separator"><xsl:text>,</xsl:text></xsl:variable>
<xsl:template match="/">{
<xsl:apply-templates select="*" mode="obj-key"/>}
</xsl:template>
<xsl:template match="*[not(* or @* )]" mode="obj-key">
<xsl:variable name="name" select="name()"/>
<xsl:if test="not(preceding-sibling::*[name()=$name])">
<xsl:text>"</xsl:text>
<xsl:call-template name="nameWithOptinalMinusToCamelcase"/>
<xsl:text>": "</xsl:text>
<xsl:value-of select="."/>
<xsl:text>"</xsl:text>
<xsl:if test="following-sibling::*[not(name()=$name)]">
<!-- If other elements with different name use comma -->
<xsl:value-of select="$separator"/>
</xsl:if>
</xsl:if>
</xsl:template>
<!-- Recursieve element node -->
<xsl:template match="*" mode="obj-key">
<xsl:variable name="name" select="name()"/>
<xsl:variable name="treatAsArray" select="count(parent::*/*[name()=$name]) > 1 or $name='ns1:Value'"/>
<xsl:if test="not(preceding-sibling::*[name()=$name])">
<xsl:text>"</xsl:text>
<xsl:call-template name="nameWithOptinalMinusToCamelcase"/>
<xsl:text>": </xsl:text>
<xsl:choose>
<xsl:when test="$treatAsArray">
<xsl:text>[</xsl:text>
<xsl:apply-templates select="." mode="obj-content"/>
<xsl:text>]</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="." mode="obj-content"/>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="following-sibling::*[not(name()=$name)]">
<!-- If other elements with different name use comma -->
<xsl:value-of select="$separator"/>
</xsl:if>
</xsl:if>
</xsl:template>
<xsl:template match="*[* or @*]" mode="obj-content">
<xsl:variable name="is-child-element-model" select="count(*) > 0"/>
<xsl:variable name="is-text-node-model" select="count(*)=0 and normalize-space(.) !=''"/>
<xsl:text>{</xsl:text>
<xsl:apply-templates select="@*" mode="attributes"/>
<xsl:if test="@* and ($is-child-element-model or $is-text-node-model)">
<xsl:value-of select="$separator"/>
</xsl:if>
<xsl:choose>
<xsl:when test="$is-text-node-model">
<xsl:apply-templates select="text()" mode="content-text"/>
</xsl:when>
<xsl:when test="$is-child-element-model">
<xsl:apply-templates select="*" mode="obj-key"/>
</xsl:when>
</xsl:choose>
<xsl:text>}</xsl:text>
<xsl:apply-templates select="." mode="following-sibling"/>
</xsl:template>
<xsl:template mode="content" match="text()[ string-length(translate(.,'0123456789',''))=0
and string-length(normalize-space(.)) > 0
and (substring(.,1,1)!='0' or string-length(.)=1)]"
priority="2">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template mode="content" match="text()[translate(.,'TRUE','true')='true']" priority="2">true</xsl:template>
<xsl:template mode="content" match="text()[translate(.,'FALSE','false')='false']" priority="2">false</xsl:template>
<xsl:template mode="content-text" match="*[@* or *]/text()">
<xsl:text>"text": </xsl:text>
<xsl:apply-templates select="." mode="content"/>
</xsl:template>
<xsl:template match="*" mode="following-sibling">
<xsl:variable name="name" select="name()"/>
<xsl:if test="following-sibling::*[name()=$name]">
<!-- If there are other elements with same name use comma -->
<xsl:value-of select="$separator"/>
<xsl:apply-templates select="following-sibling::*[name()=$name][1]" mode="obj-content"/>
</xsl:if>
</xsl:template>
<xsl:template mode="content" match="text()">
<xsl:text>"</xsl:text>
<xsl:value-of select="."/>
<xsl:text>"</xsl:text>
</xsl:template>
<!--
|| Attributen met text dienen ge-escaped te worden
-->
<xsl:template match="@*" mode="attributes">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>": "</xsl:text>
<xsl:call-template name="escape-special-json-chars"/>
<xsl:text>"</xsl:text>
<xsl:if test="position() < last()">
<xsl:value-of select="$separator"/>
</xsl:if>
</xsl:template>
<xsl:template match="@*[translate(.,'FALSE','false')='false']" mode="attributes">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>": false</xsl:text>
<xsl:if test="position() < last()">
<xsl:value-of select="$separator"/>
</xsl:if>
</xsl:template>
<xsl:template match="@*[translate(.,'TRUE','true')='true']" mode="attributes">
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>": true</xsl:text>
<xsl:if test="position() < last()">
<xsl:value-of select="$separator"/>
</xsl:if>
</xsl:template>
<xsl:template match="@*[string-length(translate(.,'0123456789',''))=0 and string-length(normalize-space(.)) > 0 and (substring(.,1,1)!='0' or string-length(.)=1)]" mode="attributes" >
<xsl:text>"</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>": </xsl:text>
<xsl:value-of select="."/>
<xsl:if test="position() < last()">
<xsl:value-of select="$separator"/>
</xsl:if>
</xsl:template>
<xsl:variable name="escChr" select="'\'"/>
<xsl:variable name="dqt">"</xsl:variable>
<xsl:variable name="cr" select="' '"/>
<xsl:variable name="nl" select="' '"/>
<xsl:variable name="sls" select="'\'"/>
<xsl:variable name="tab" select="'	'"/>
<xsl:template name="escape-special-json-chars">
<xsl:variable name="textSlsEsc">
<xsl:call-template name="escapeString">
<xsl:with-param name="text" select="." />
<xsl:with-param name="escape" select="$sls"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="textCrEsc">
<xsl:call-template name="escapeString">
<xsl:with-param name="text" select="$textSlsEsc" />
<xsl:with-param name="escape" select="$cr"/>
<xsl:with-param name="with" select="'\r'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="textLfEsc">
<xsl:call-template name="escapeString">
<xsl:with-param name="text" select="$textCrEsc" />
<xsl:with-param name="escape" select="$nl"/>
<xsl:with-param name="with" select="'\n'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="textDqtEsc">
<xsl:call-template name="escapeString">
<xsl:with-param name="text" select="$textLfEsc" />
<xsl:with-param name="escape" select="$dqt"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="textTabEsc">
<xsl:call-template name="escapeString">
<xsl:with-param name="text" select="$textDqtEsc" />
<xsl:with-param name="escape" select="$tab"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$textTabEsc"/>
</xsl:template>
<xsl:template name="escapeString">
<xsl:param name="text"/>
<xsl:param name="escape"/>
<xsl:param name="with" select="concat($escChr,$escape)"/>
<xsl:param name="prevText" select="'ditWordtNooitGevonden'"/>
<xsl:choose>
<xsl:when test="contains($text,$escape)">
<xsl:variable name="testChar">
<xsl:choose>
<xsl:when test="$escape=$escChr">
<xsl:value-of select="substring(substring-after($text,$escape),1,1)"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="before" select="substring-before($text,$escape)"/>
<xsl:value-of select="substring($before, string-length($before))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="testCharIsEscapeChr" select="$testChar=$escChr"/>
<xsl:choose>
<xsl:when test="$testCharIsEscapeChr">
<!-- Karakter is al ge-escaped -->
<xsl:value-of select="substring-before($text,$with)"/>
<xsl:value-of select="$with"/>
<xsl:call-template name="escapeString">
<xsl:with-param name="text" select="substring-after($text,$with)"/>
<xsl:with-param name="escape" select="$escape"/>
<xsl:with-param name="with" select="$with"/>
<xsl:with-param name="prevText" select="$text"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-before($text,$escape)"/>
<xsl:value-of select="$with"/>
<xsl:call-template name="escapeString">
<xsl:with-param name="text" select="substring-after($text,$escape)"/>
<xsl:with-param name="escape" select="$escape"/>
<xsl:with-param name="with" select="$with"/>
<xsl:with-param name="prevText" select="$text"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'"/>
<!--
|| json properties can't have a minus sign
-->
<xsl:template name="nameWithOptinalMinusToCamelcase">
<xsl:param name="name" select="name()"/>
<xsl:choose>
<xsl:when test="contains($name,'-')">
<xsl:value-of select="substring-before($name,'-')"/>
<xsl:variable name="after" select="substring-after($name,'-')"/>
<xsl:value-of select="translate(substring($after,1,1), $lower, $upper)"/>
<xsl:call-template name="nameWithOptinalMinusToCamelcase">
<xsl:with-param name="name" select="substring($after,2)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
正在申请xml:
<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn://xyz/soap/cegtar/unique">
<SOAP-ENV:Body>
<ns1:abcResponse>
<ns1:abc id="12345">
<ns1:Rovatok/>
<ns1:ScoringAdatok>
<ns1:XData tipus="11" megnevezes="APEH hátralék (rendezetlen)">
<ns1:Value num="1" subtype="xbool">false</ns1:Value>
</ns1:XData>
<ns1:XData tipus="13" megnevezes="Egyéb VH (rendezetlen)">
<ns1:Value num="1" subtype="xbool">false</ns1:Value>
</ns1:XData>
<ns1:XData tipus="46" megnevezes="Cég-állapot (APAFI helyett)">
<ns1:Value num="1" subtype="xdate">0000-00-00</ns1:Value>
<ns1:Value num="2" subtype="xnum">0</ns1:Value>
</ns1:XData>
</ns1:ScoringAdatok>
</ns1:abc>
</ns1:abcResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
结果:
{
"SOAP-ENV:Envelope": {
"SOAP-ENV:Body": {
"ns1:abcResponse": {
"ns1:abc": {
"id": 12345,
"ns1:Rovatok": "",
"ns1:ScoringAdatok": {
"ns1:XData": [
{
"tipus": 11,
"megnevezes": "APEH hátralék (rendezetlen)",
"ns1:Value": [
{
"num": 1,
"subtype": "xbool",
"text": false
}
]
},
{
"tipus": 13,
"megnevezes": "Egyéb VH (rendezetlen)",
"ns1:Value": [
{
"num": 1,
"subtype": "xbool",
"text": false
}
]
},
{
"tipus": 46,
"megnevezes": "Cég-állapot (APAFI helyett)",
"ns1:Value": [
{
"num": 1,
"subtype": "xdate",
"text": "0000-00-00"
},
{
"num": 2,
"subtype": "xnum",
"text": 0
}
]
}
]
}
}
}
}
}
}