使用 XPath 3.1 fn:serialize 进行 JSON 序列化

Posted

技术标签:

【中文标题】使用 XPath 3.1 fn:serialize 进行 JSON 序列化【英文标题】:JSON serialization with XPath 3.1 fn:serialize 【发布时间】:2017-11-20 11:33:26 【问题描述】:

我在 Saxon-HE 9.8 中使用 XSLT 3.0,并希望将 JSON 文档作为 JSON-LD 中的链接数据使用。在 JSON-LD 中,完整的 HTTP URI 通常显示为值。

当我使用 XPath 3.1 fn:serialize 将数据往返返回 JSON 时,http:// 中的斜线字符被转义。序列化回 JSON 时是否可以避免这种转义?

fn:parse-json 函数有一个escape 参数,可以设置为true()false(),但我没有看到fn:serialize 有类似的东西。

我可以使用fn:replace 删除转义字符,但想知道是否有我缺少的内置方法。

一个示例样式表:

<?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>

没有fn:replace,结果是"@context":"http:\/\/schema.org"。使用fn:replace,结果为"@context":"http://schema.org"

【问题讨论】:

为了它的价值,我用 BaseX 和 Altova 尝试了let $j := ' "@context": "http://schema.org" ' return $j =&gt; parse-json(map 'escape': false(), 'liberal': true()) =&gt; serialize(map 'method': 'json'),它们也将/ 转义为\/,所以给"@context": "http:\/\/schema.org" w3.org/TR/xslt-xquery-serialization-31/#to-a-json-string 建议编码是输出方法 json 的规范要求的。 【参考方案1】:

使用 Saxon 9.8,如果将 serialize 函数调用为 =&gt; serialize(map 'method': 'json', 'use-character-maps' : map '/' : '/' ),则将按原样输出固相线,而不是作为 \/ 转义。

参见规范 https://www.w3.org/TR/xpath-functions-31/#func-serialize 解释 serialize 的第二个参数是 map 其中 use-character-maps 本身就是 map(xs:string, xs:string)? 并且“键是要映射的字符(作为 xs:string 实例) ,并且其对应的值是要替换这些字符的字符串”和3.1 serialization spec 说“字符串中定义了字符映射的任何字符......都被字符映射中定义的替换字符串替换。”和“输入字符串中的任何其他字符(但不是由字符映射产生的字符)都是 [...] JSON 转义的候选对象。”。

因此,基本上,如果您将该映射中的字符列出为映射到自身,则 JSON 编码不会进一步改变它们。

【讨论】:

以上是关于使用 XPath 3.1 fn:serialize 进行 JSON 序列化的主要内容,如果未能解决你的问题,请参考以下文章

.Net Core 3.1 和 .Net 5.0 是不是支持 XPath 2.0?

序列化问题

13_Python_解析库_Xpath的使用

爬虫进阶数据提取-lxml模块(万能操作)

❤️通宵爆肝两万字xpath教程+实战练习❤️

jQuery - 基于serializeArray的serializeObject