Created
November 14, 2018 07:49
-
-
Save dmj/83e1e1cd003d448fa8df2d94e4481537 to your computer and use it in GitHub Desktop.
JSON-Pointer over canonical XML representation of JSON (just for the fun of it)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<json:map xmlns:json="http://www.w3.org/2005/xpath-functions"> | |
<json:array key="foo"> | |
<json:string>bar</json:string> | |
<json:string>baz</json:string> | |
</json:array> | |
<json:number key="">0</json:number> | |
<json:number key="a/b">1</json:number> | |
<json:number key="c%d">2</json:number> | |
<json:number key="e^f">3</json:number> | |
<json:number key="g|h">4</json:number> | |
<json:number key="i\j">5</json:number> | |
<json:number key="k"l">6</json:number> | |
<json:number key=" ">7</json:number> | |
<json:number key="m~n">8</json:number> | |
</json:map> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<xsl:transform version="3.0" | |
xmlns:json="http://www.w3.org/2005/xpath-functions" | |
xmlns:jptr="tag:[email protected],2018:RFC6901" | |
xmlns:xs="http://www.w3.org/2001/XMLSchema" | |
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> | |
<!-- | |
Returns the selected JSON information item or the empty sequence if the pointer does not denote | |
an information item in the JSON document. Expects the pointer to be a sequence of reference | |
tokens, i.e. the result of applying tokenize() on the pointer's string representation. | |
--> | |
<xsl:function name="jptr:evaluate" as="element()?"> | |
<xsl:param name="context" as="element()?"/> | |
<xsl:param name="pointer" as="xs:string*"/> | |
<xsl:variable name="token" select="jptr:unescape($pointer[1])"/> | |
<xsl:choose> | |
<xsl:when test="empty($context)"/> | |
<xsl:when test="empty($pointer)"> | |
<xsl:sequence select="$context"/> | |
</xsl:when> | |
<xsl:when test="$token = ''"> | |
<xsl:sequence select="jptr:evaluate($context, $pointer[position() gt 1])"/> | |
</xsl:when> | |
<xsl:when test="$context/self::json:map"> | |
<xsl:sequence select="jptr:evaluate($context/json:*[@key = $token], $pointer[position() gt 1])"/> | |
</xsl:when> | |
<xsl:when test="$context/self::json:array and matches($token, '[0-9]+')"> | |
<xsl:sequence select="jptr:evaluate($context/json:*[position() eq (number($token) + 1)], $pointer[position() gt 1])"/> | |
</xsl:when> | |
</xsl:choose> | |
</xsl:function> | |
<xsl:function name="jptr:unescape" as="xs:string?"> | |
<xsl:param name="token" as="xs:string?"/> | |
<xsl:value-of select="replace(replace($token, '~1', '/'), '~0', '~')"/> | |
</xsl:function> | |
</xsl:transform> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE description [<!ENTITY example SYSTEM "rfc6901.xml">]> | |
<description xmlns="http://www.jenitennison.com/xslt/xspec" | |
xmlns:xi="http://www.w3.org/2001/XInclude" | |
xmlns:jptr="tag:[email protected],2018:RFC6901" | |
xmlns:json="http://www.w3.org/2005/xpath-functions" | |
stylesheet="rfc6901.xsl"> | |
<scenario label="When jptr:unescape is called"> | |
<scenario label="with a pointer segment containing an encoded forward slash"> | |
<call function="jptr:unescape"> | |
<param name="token" as="xs:string">foo~1bar</param> | |
</call> | |
<expect label="the forward slash is unescaped" select="'foo/bar'"/> | |
</scenario> | |
<scenario label="with a pointer segment containing an encoded tilde"> | |
<call function="jptr:unescape"> | |
<param name="token" as="xs:string">foo~0bar</param> | |
</call> | |
<expect label="the tilde is unescaped" select="'foo~bar'"/> | |
</scenario> | |
<scenario label="with a pointer segment containing an encoded tilde followed by a one"> | |
<call function="jptr:unescape"> | |
<param name="token" as="xs:string">~01</param> | |
</call> | |
<expect label="only the tilde is unescaped" select="'~1'"/> | |
</scenario> | |
</scenario> | |
<scenario label="When jptr:evaluate is called"> | |
<scenario label="with the empty string as pointer"> | |
<call function="jptr:evaluate"> | |
<param name="context"> | |
&example; | |
</param> | |
<param name="pointer"/> | |
</call> | |
<expect label="the entire document is returned"> | |
<json:map>...</json:map> | |
</expect> | |
</scenario> | |
<scenario label="with a string denoting the member of a map"> | |
<call function="jptr:evaluate"> | |
<param name="context"> | |
&example; | |
</param> | |
<param name="pointer" as="xs:string+" select="tokenize('/foo', '/')"/> | |
</call> | |
<expect label="the member with the same name is returned"> | |
<json:array key="foo">...</json:array> | |
</expect> | |
</scenario> | |
<scenario label="with a string not denoting the member of a map"> | |
<call function="jptr:evaluate"> | |
<param name="context"> | |
&example; | |
</param> | |
<param name="pointer" as="xs:string+" select="tokenize('/foo/bar', '/')"/> | |
</call> | |
<expect label="the empty sequence is returned"/> | |
</scenario> | |
<scenario label="with a numeric string denoting an array index"> | |
<call function="jptr:evaluate"> | |
<param name="context"> | |
&example; | |
</param> | |
<param name="pointer" as="xs:string+" select="tokenize('/foo/0', '/')"/> | |
</call> | |
<expect label="the array member at this position is returned"> | |
<json:string>bar</json:string> | |
</expect> | |
</scenario> | |
<scenario label="with a numeric string not denoting an array index"> | |
<call function="jptr:evaluate"> | |
<param name="context"> | |
&example; | |
</param> | |
<param name="pointer" as="xs:string+" select="tokenize('/foo/3', '/')"/> | |
</call> | |
<expect label="the empty sequence is returned"/> | |
</scenario> | |
</scenario> | |
</description> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment