JSON serialization with XPath 3.1 fn:serialize
Asked Answered
I

1

7

I am using XSLT 3.0 in Saxon-HE 9.8 and would like to work with JSON documents as linked data in JSON-LD. In JSON-LD, full HTTP URIs often appear as values.

When I use the XPath 3.1 fn:serialize to round-trip the data back to JSON, the solidus characters in http:// are escaped. Is it possible to avoid this escaping when serializing back to JSON?

The fn:parse-json function has an escape parameter that can be set to true() or false(), but I don't see anything similar for fn:serialize.

I can remove the escape characters with fn:replace, but would like to know whether there is a built-in way to do it that I am missing.

An example stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:array="http://www.w3.org/2005/xpath-functions/array"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">

    <xsl:output omit-xml-declaration="yes"/>

    <xsl:variable name="j" expand-text="no"> { "@context": "http://schema.org" } </xsl:variable>

    <xsl:template name="init">
        <xsl:sequence
            select="            
                $j => parse-json(map {'escape': false(), 'liberal': true()})
                => serialize(map {'method': 'json'})
                => replace('\\/', '/')
            "/>
    </xsl:template>

</xsl:stylesheet>

Without fn:replace, the result is {"@context":"http:\/\/schema.org"}. With fn:replace, the result is {"@context":"http://schema.org"}.

Interfluent answered 17/6, 2017 at 23:42 Comment(2)
For what it is worth, I tried let $j := ' { "@context": "http://schema.org" } ' return $j => parse-json(map {'escape': false(), 'liberal': true()}) => serialize(map {'method': 'json'}) with BaseX and with Altova and they too escape the / as \/ so give "@context": "http:\/\/schema.org".Haim
w3.org/TR/xslt-xquery-serialization-31/#to-a-json-string suggests the encoding is mandated by spec for output method json.Haim
H
7

Using Saxon 9.8, if the serialize function is called as => serialize(map {'method': 'json', 'use-character-maps' : map { '/' : '/' }}), the solidus is output as is and not escaped as \/.

See the spec https://www.w3.org/TR/xpath-functions-31/#func-serialize explaining the second argument to serialize being a map where the use-character-maps is itself a map(xs:string, xs:string)? and the "keys are the characters to be mapped (as xs:string instances), and whose corresponding values are the strings to be substituted for these characters" and the 3.1 serialization spec saying "Any character in the string for which character mapping is defined ... is substituted by the replacement string defined in the character map." and "Any other character in the input string (but not a character produced by character mapping) is a candidate for [...] JSON escaping.".

So basically if you list characters in that map as being mapped to themselves the JSON encoding will not alter them further.

Haim answered 18/6, 2017 at 12:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.