控制 JSON 中 xml 的序列化

controlling serialisation of xml inside JSON

提问人:MrD at KookerellaLtd 提问时间:10/31/2023 最后编辑:kometenMrD at KookerellaLtd 更新时间:10/31/2023 访问量:31

问:

xslt 3.0 撒克逊 PE 11.4

我有这个工作,但偶然。

请考虑此输入。

<?xml version="1.0" encoding="UTF-8"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet">
</Workbook>

我想得到这个 JSON(编码很难......所以我认为我需要转义“”字符,而且我不太担心“/”的 JSON 转义)

{
   "xmlData": "<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"><\/Workbook>"
}

所以基本上一些外部伪代码就可以了。

json = JSON.Read("file.json")
xmlString = json["xmlDate"]
xml = XDocument.Parse(xmlString)

并将 XML 读入某个 XML 模型中。

所以我的尝试是这样的。

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:array="http://www.w3.org/2005/xpath-functions/array"
    exclude-result-prefixes="map array">
    <xsl:output method="json"/>
    
    <xsl:template match="/">
        <xsl:variable name="transformed-xml">
            <xsl:copy-of select="."/>
        </xsl:variable>
        
        <xsl:map>
            <xsl:map-entry key="'xmlData'" select="serialize($transformed-xml)"/>
        </xsl:map>
    </xsl:template>
</xsl:stylesheet>

第一次尝试

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:array="http://www.w3.org/2005/xpath-functions/array"
    exclude-result-prefixes="map array">
    <xsl:output method="json"/>
    
    <xsl:template match="/">
        <xsl:variable name="transformed-xml">
            <xsl:copy-of select="."/>
        </xsl:variable>
        
        <xsl:variable name="json-string">
            <!-- Convert the transformed XML to a JSON string -->
            <xsl:value-of select="serialize($transformed-xml)"/>
        </xsl:variable>
        
        <xsl:map>
            <xsl:map-entry key="'xmlData'" select="$json-string"/>
        </xsl:map>
    </xsl:template>
</xsl:stylesheet>

给我这个

{
   "xmlData": "&lt;Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"&gt;\n&lt;\/Workbook&gt;"
}

讨厌。。。它的“xml”逃脱了“<”、“>”和新行......不是 100% 确定为什么,我认为 serialise 将字符串转义为“xml”格式,因为它在文档节点中嵌入了“text”节点?

还行。。。尝试 2

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:array="http://www.w3.org/2005/xpath-functions/array"
    exclude-result-prefixes="map array">
    <xsl:output method="json"/>
    
    <xsl:template match="/">
        <xsl:variable name="transformed-xml">
            <xsl:copy-of select="."/>
        </xsl:variable>
        
        <xsl:map>
            <xsl:map-entry key="'xmlData'" select="serialize($transformed-xml)"/>
        </xsl:map>
    </xsl:template>
</xsl:stylesheet>

{
   "xmlData": "<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\">\n<\/Workbook>"
}

哪个有效!因为它不是第一个将其嵌入到文档节点内的文本节点中?

P.S. 我认为这是一种明智的方法,以后不会咬我?

XSLT-3.0

评论


答:

1赞 Martin Honnen 10/31/2023 #1

JSON 输出可以序列化节点,因此

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all">
  
  <xsl:output method="json" indent="yes"/>

  <xsl:template match="/">
    <xsl:sequence select="map { 'xmlData' : . }"/>
  </xsl:template>
  
</xsl:stylesheet>

例如(撒克逊语 HE 12.3)

{ "xmlData":"<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\">\n<\/Workbook>" }

还有一个序列化属性 https://www.w3.org/TR/xslt-xquery-serialization-31/#JSON_JSON-NODE-OUTPUT-METHOD 用于控制节点序列化方法,这些节点序列化方法作为 json 输出方法的一部分进行序列化。

所以基本上我不确定你为什么要尝试在你自己的代码中序列化 XML。

评论

0赞 MrD at KookerellaLtd 10/31/2023
我想如果我只是给 json 序列化器一些随机的 xml,它就会开始寻找映射/数组将其转换为 JSON......所以我认为我必须明确地这样做(有效地镜像您解析 JSON 的读取过程......提取字符串...和部分 XML)