Mercurial > pub > ImplabNet
diff Implab/Xml/json.xsl @ 264:3a6e18c432be v3
Added XmlToJson xsl transformation.
Added JsonXmlReader.CreateJsonXmlReader(...) methods
Added SerializationHelpers.SerializeJson/DeserializeJson methods
author | cin |
---|---|
date | Mon, 16 Apr 2018 18:43:49 +0300 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/Xml/json.xsl Mon Apr 16 18:43:49 2018 +0300 @@ -0,0 +1,252 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:exsl="http://exslt.org/common"> + <xsl:output method="text" /> + + <xsl:template match="/"> + <xsl:apply-templates mode="json-value" /> + </xsl:template> + + + <!-- handle json-object --> + + <xsl:template match="*" mode="json-object"> + <xsl:call-template name="write-members"/> + </xsl:template> + + <xsl:template match="*|@*" mode="json-member"> + <xsl:param name="values" select="."/> + <xsl:call-template name="write-string"> + <xsl:with-param name="text"><xsl:apply-templates select="." mode="json-member-name"/></xsl:with-param> + </xsl:call-template> + <xsl:text> : </xsl:text> + <xsl:apply-templates select="." mode="json-member-value"> + <xsl:with-param name="values" select="$values"/> + </xsl:apply-templates> + </xsl:template> + + <xsl:template match="*" mode="json-member-name"> + <xsl:value-of select="local-name(.)"/> + </xsl:template> + + <xsl:template match="@*" mode="json-member-name"> + <xsl:value-of select="concat('_',local-name(.))"/> + </xsl:template> + + <xsl:template match="*|@*" mode="json-member-value"> + <xsl:param name="values" select="."/> + <xsl:choose> + <xsl:when test="count($values) > 1"> + <xsl:call-template name="write-array"> + <xsl:with-param name="values" select="$values"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:apply-templates select="$values" mode="json-value"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template match="*|@*" mode="json-array-item"> + <xsl:apply-templates select="." mode="json-value"/> + <xsl:if test="position() != last()"> + <xsl:text>, </xsl:text> + </xsl:if> + </xsl:template> + + <!-- handle json-value --> + + <xsl:template match="text()[. = 'true'] | @*[. = 'true']" mode="json-value"> + <xsl:text>true</xsl:text> + </xsl:template> + + <xsl:template match="text()[. = 'false'] | @*[. = 'false']" + mode="json-value"> + <xsl:text>false</xsl:text> + </xsl:template> + + <xsl:template match="text()[string(number(.)) != 'NaN'] | @*[string(number(.)) != 'NaN']" + mode="json-value"> + <xsl:value-of select="number(.)" /> + </xsl:template> + + <xsl:template match="text()|@*" mode="json-value"> + <xsl:call-template name="write-string"> + <xsl:with-param name="text" select="."/> + </xsl:call-template> + </xsl:template> + + <xsl:template match="*[boolean(* | @*) or not(text())]" mode="json-value"> + <xsl:call-template name="write-object"/> + </xsl:template> + + <xsl:template match="*[@xsi:nil = 'true']" mode="json-value"> + <xsl:text>null</xsl:text> + </xsl:template> + + <!-- template traits --> + + <xsl:template name="write-value"> + <xsl:param name="value" select="."/> + <xsl:apply-templates select="$value" mode="json-value"/> + </xsl:template> + + <xsl:template name="write-member"> + <xsl:param name="name"/> + <xsl:param name="value"/> + <xsl:call-template name="write-string"> + <xsl:with-param name="text" select="$name"/> + </xsl:call-template> + <xsl:text> : </xsl:text> + <xsl:apply-templates select="$value" mode="json-value"/> + </xsl:template> + + <xsl:template name="write-member-string"> + <xsl:param name="name"/> + <xsl:param name="value"/> + <xsl:call-template name="write-string"> + <xsl:with-param name="text" select="$name"/> + </xsl:call-template> + <xsl:text> : </xsl:text> + <xsl:call-template name="write-string"> + <xsl:with-param name="text" select="$value"/> + </xsl:call-template> + </xsl:template> + + <xsl:template name="write-member-array"> + <xsl:param name="name"/> + <xsl:param name="values"/> + <xsl:call-template name="write-string"> + <xsl:with-param name="text" select="$name"/> + </xsl:call-template> + <xsl:text> : </xsl:text> + <xsl:call-template name="write-array"> + <xsl:with-param name="values" select="$values"/> + </xsl:call-template> + </xsl:template> + + <xsl:template name="write-separator"> + <xsl:text>, </xsl:text> + </xsl:template> + + <!-- specialized template traits --> + + <xsl:template name="write-string"> + <xsl:param name="text"/> + <xsl:text>"</xsl:text> + <xsl:call-template name="escape-bs-string"> + <xsl:with-param name="s" select="$text"/> + </xsl:call-template> + <xsl:text>"</xsl:text> + </xsl:template> + + <xsl:template name="write-object"> + <xsl:param name="value" select="."/> + <xsl:text>{ </xsl:text> + <xsl:apply-templates select="$value" mode="json-object"/> + <xsl:text> }</xsl:text> + </xsl:template> + + <xsl:template name="write-array"> + <xsl:param name="values"/> + + <xsl:text>[ </xsl:text> + <xsl:apply-templates select="$values" mode="json-array-item"/> + <xsl:text> ]</xsl:text> + </xsl:template> + + <xsl:template name="write-members"> + <xsl:param name="members" select="*"/> + + <xsl:for-each select="$members"> + <xsl:variable name="current" select="."/> + <xsl:variable name="values" select="$members[local-name(.) = local-name($current)]"/> + <xsl:if test="generate-id($current) = generate-id($values)"> + <xsl:if test="position()>1"> + <xsl:call-template name="write-separator"/> + </xsl:if> + <xsl:apply-templates select="$current" mode="json-member"> + <xsl:with-param name="values" select="$values"/> + </xsl:apply-templates> + </xsl:if> + </xsl:for-each> + </xsl:template> + + <!-- escape string --> + <!-- + Copyright (c) 2006,2008 Doeke Zanstra + All rights reserved. + https://github.com/doekman/xml2json-xslt/blob/master/xml2json.xslt + --> + <!-- Escape the backslash (\) before everything else. --> + <xsl:template name="escape-bs-string"> + <xsl:param name="s"/> + <xsl:choose> + <xsl:when test="contains($s,'\')"> + <xsl:call-template name="escape-quot-string"> + <xsl:with-param name="s" select="concat(substring-before($s,'\'),'\\')"/> + </xsl:call-template> + <xsl:call-template name="escape-bs-string"> + <xsl:with-param name="s" select="substring-after($s,'\')"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="escape-quot-string"> + <xsl:with-param name="s" select="$s"/> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <!-- Escape the double quote ("). --> + <xsl:template name="escape-quot-string"> + <xsl:param name="s"/> + <xsl:choose> + <xsl:when test="contains($s,'"')"> + <xsl:call-template name="encode-string"> + <xsl:with-param name="s" select="concat(substring-before($s,'"'),'\"')"/> + </xsl:call-template> + <xsl:call-template name="escape-quot-string"> + <xsl:with-param name="s" select="substring-after($s,'"')"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="encode-string"> + <xsl:with-param name="s" select="$s"/> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <!-- Replace tab, line feed and/or carriage return by its matching escape code. Can't escape backslash + or double quote here, because they don't replace characters (� becomes \t), but they prefix + characters (\ becomes \\). Besides, backslash should be seperate anyway, because it should be + processed first. This function can't do that. --> + <xsl:template name="encode-string"> + <xsl:param name="s"/> + <xsl:choose> + <!-- tab --> + <xsl:when test="contains($s,'	')"> + <xsl:call-template name="encode-string"> + <xsl:with-param name="s" select="concat(substring-before($s,'	'),'\t',substring-after($s,'	'))"/> + </xsl:call-template> + </xsl:when> + <!-- line feed --> + <xsl:when test="contains($s,'
')"> + <xsl:call-template name="encode-string"> + <xsl:with-param name="s" select="concat(substring-before($s,'
'),'\n',substring-after($s,'
'))"/> + </xsl:call-template> + </xsl:when> + <!-- carriage return --> + <xsl:when test="contains($s,'
')"> + <xsl:call-template name="encode-string"> + <xsl:with-param name="s" select="concat(substring-before($s,'
'),'\r',substring-after($s,'
'))"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise><xsl:value-of select="$s"/></xsl:otherwise> + </xsl:choose> + </xsl:template> + +</xsl:stylesheet> \ No newline at end of file