37

我正在寻找一种 json 解析将按原样获取信息的方式(就像它是 CDATA 一样) - 而不是尝试序列化它。我们同时使用 .net 和 java(客户端和服务器)——所以答案应该是关于 JSON 结构 有没有办法实现这种结构?

谢谢。

4

4 回答 4

22

JSON 中没有等效的 XML CDATA。但是您可以使用 base64 之类的方法将消息编码为字符串文字。有关更多详细信息,请参阅此问题

于 2013-02-18T12:16:32.077 回答
0

这是上述拉曼建议的发展。

我喜欢 JSON 格式,但有两件事我希望能够用它做而不能做:

  1. 使用文本编辑器将一些任意文本粘贴到值中
  2. 如果 XML 包含 CDATA 部分,则在 XML 和 JSON 之间进行透明转换。

该线程与这两个问题密切相关。

我建议通过以下方式克服这个问题,这不会破坏 JSON 的正式定义,我想知道如果我这样做是否会存储任何问题?

  1. 定义一个与 JSON 兼容的字符串格式,如下所示:

    "<![CDATA[ (some text, escaped according to JSON rules) ]]>"

  2. 用我最喜欢的编程语言编写一个 Unescape 例程,它将<![CDATA[ and ]]>. 这将在向我的文本编辑器提供任何 JSON 文件之前调用。

  3. <![CDATA[ and ]]>编写补充例程以在编辑文件后调用,该例程根据 JSON 规则重新转义两者之间的任何内容。

然后,为了将任意数据粘贴到文件中,我需要做的就是在 JSON 字符串中键入任意数据的开始和结束信号 <![CDATA[ before and ]]>

这是在 Python3 中在文本编辑之前和之后调用的例程: lang-python3

escape_list = {
    8 : 'b',
    9 : 't',
    10: 'n',
    12: 'f',
    13: 'r',
    34: '"',
}   #List of ASCII character codes to escape, with their escaped equivalents

escape_char = "\\"  #this must be dealt with separately
unlikely_string = "ZzFfGgQqWw"

shebang = "#!/json/unesc\n"
start_cdata = "<![CDATA["
end_cdata = "]]>"

def escapejson(json_path):

    if (os.path.isfile(json_path)): #If it doesn't exist, we can't update it
        with open(json_path) as json_in:
            data_in = json_in.read()   #use read() 'cos we're goint to treat as txt
        #Set direction of escaping
        if (data_in[:len(shebang)] == shebang):   #data is unescaped, so re-escape
            data_in = data_in[len(shebang):] 
            unescape = False
            data_out = ""
        else:
            data_out = shebang
            unescape = True 

        while (data_in != ""):  #while there is still some input to deal with
            x = data_in.find(start_cdata)
            x1 = data_in.find(end_cdata)
            if (x > -1):    #something needs escaping
                if (x1 <0):
                    print ("Unterminated CDATA section!")
                    exit()
                elif (x1 < x):  #end before next start
                    print ("Extra CDATA terminator!")
                    exit()
                data_out += data_in[:x]
                data_in = data_in[x:]
                y = data_in.find(end_cdata) + len(end_cdata)
                to_fix = data_in[:y]    #this is what we're going to (un)escape
                if (to_fix[len(start_cdata):].find(start_cdata) >= 0):
                    print ("Nested CDATA sections not supported!")
                    exit()
                data_in = data_in[y:]   #chop data to fix from front of source
                if (unescape):
                    to_fix = to_fix.replace(escape_char + escape_char,unlikely_string)
                    for each_ascii in escape_list:
                        to_fix = to_fix.replace(escape_char + escape_list[each_ascii],chr(each_ascii))
                    to_fix = to_fix.replace(unlikely_string,escape_char)
                else:
                    to_fix = to_fix.replace(escape_char,escape_char + escape_char)
                    for each_ascii in escape_list:
                        to_fix = to_fix.replace(chr(each_ascii),escape_char + escape_list[each_ascii],)
                data_out += to_fix
            else:
                if (x1 > 0):
                    print ("Termination without start!")
                    exit()
                data_out += data_in
                data_in = ""

        #Save all to file of same name in same location
        try:
            with open(json_path, 'w') as outfile:
                outfile.write(data_out)
        except IOError as e:
            print("Writing "+ json_path + " failed "+ str(e))
    else:
        print("JSON file not found")

对以下合法 JSON 数据进行操作

{
    "test": "<![CDATA[\n We can put all sorts of wicked things like\n \\slashes and\n \ttabs and \n \"double-quotes\"in here!]]>"
}

...将产生以下内容:

#!/json/unesc
{
    "test": "<![CDATA[
 We can put all sorts of wicked things like
 \slashes and
    tabs and 
 "double-quotes"in here!]]>"
}

在这种形式中,您可以在标记之间粘贴任何文本。再次调用例程会将其更改回原始的合法 JSON。

我认为这也可以在使用 CDATA 区域转换为 XML 或从 XML 转换时起作用。(接下来我要试试!)

于 2020-08-25T09:00:48.457 回答
0

您可以创建 YAML 文件并转换为 JSON。例如:

测试.yaml

storage:
  files:
  - filesystem: root
    path: /etc/sysconfig/network/ifcfg-eth0
    mode: 644
    overwrite: true
    contents:
      source: |
        data:,
        IPV6INIT=yes
        IPV6_AUTOCONF=yes

...然后运行yaml2json_pretty(稍后显示),如下所示:

#!/bin/bash

cat test.yaml | yaml2json_pretty > test.json

...产生:

测试.json

{
  "storage": {
    "files": [
      {
        "filesystem": "root",
        "path": "/etc/sysconfig/network/ifcfg-eth0",
        "mode": 644,
        "overwrite": true,
        "contents": {
          "source": "data:,\nIPV6INIT=yes\nIPV6_AUTOCONF=yes\n"
        }
      }
    ]
  }
}

这是 yaml2json_pretty 的源代码:

#!/usr/bin/env python3

import sys, yaml, json
print(json.dumps(yaml.load(sys.stdin.read(),Loader=yaml.FullLoader), sort_keys=False, indent=2))

更多与此类似的技巧:http yaml2json_pretty: //github.com/frgomes/bash-scripts

于 2021-02-10T02:00:36.143 回答
-8

http://www.json.org/详细描述了 JSON 格式。根据它,JSON 不支持“类似于 CDATA”的值类型。

要实现 CDATA 结构,您可以应用自定义逻辑来处理基于字符串的值(并且对于 .net 和 java 实现都以相同的方式进行)。例如

{ 
  "type" : "CDATA",
  "value" : "Value that I will handle with my custom logic on java and .net side"
}
于 2013-02-18T12:14:52.067 回答