JSON值是否可以包含多行字符串

时间:2013-05-22 11:03:20

标签: json multiline

我正在编写一个可由Java程序读取的JSON文件。片段如下......

{
  "testCases" :
  {
    "case.1" :
    {
      "scenario" : "this the case 1.",
      "result" : "this is a very long line which is not easily readble.
                  so i would like to write it in multiple lines.
                  but, i do NOT require any new lines in the output.
                  I need to split the string value in this input file only.
                  such that I don't require to slide the horizontal scroll again and again while verifying the correctness of the statements.
                  the prev line, I have shown, without splitting just to give a feel of my problem"
    }
  }
}

6 个答案:

答案 0 :(得分:47)

查看the specification! JSON语法的 char 生产可以采用以下值:

  • 任何-Unicode的字符除外 - " - 或 - \ - 或控制字符
  • \"
  • \\
  • \/
  • \b
  • \f
  • \n
  • \r
  • \t
  • \u 四个十六进制数字

换行符是“控制字符”,所以不,你的字符串中可能没有文字换行符。但是,您可以使用所需的\n\r的任意组合对其进行编码。

JSONLint工具确认您的JSON无效。


更新:如果您想在JSON语法中写入换行符而不在数据中实际包含换行符,那么您甚至会失败。虽然JSON旨在在某种程度上对人类友好,但它仍然是数据,并且您正在尝试对该数据应用任意格式。这绝对不是JSON的意思。

答案 1 :(得分:24)

我不确定您的确切要求,但提高“可读性”的一种可能解决方案是将其存储为数组。

{
  "testCases" :
  {
    "case.1" :
    {
      "scenario" : "this the case 1.",
      "result" : ["this is a very long line which is not easily readble.",
                  "so i would like to write it in multiple lines.",
                  "but, i do NOT require any new lines in the output."]
    }
  }
}

}

在需要时再次加入

result.join(" ")

答案 2 :(得分:3)

我可以理解这个问题不是关于如何使用json传递带控制符号的字符串,而是如何在文件中存储和恢复json,您可以使用编辑器控件符号拆分字符串。

如果要在文件中存储多行字符串,则文件不会存储有效的json对象。但是,如果仅在程序中使用json文件,则可以根据需要存储数据,并在每次将其加载到程序时手动删除文件中的所有换行符,然后传递给json解析器。

或者,或者哪个更好,您可以根据需要编辑json数据源文件,然后使用一些实用程序删除所有新行到有效json文件你的程序将使用哪些。

答案 3 :(得分:2)

不是很好的解决方案,但您可以尝试 hjson 工具。 Link。它允许您在编辑器中编写多行文本,然后将其转换为正确的有效JSON格式。 注意:它为新行添加'\ n'个字符,但您可以使用“全部替换...”功能在任何文本编辑器中删除它们。

P.S。应该是对问题的评论,但没有足够的回购,对不起。

答案 4 :(得分:1)

我相信这取决于你正在使用的json解释器...在普通的javascript中你可以使用行终止符

{
  "testCases" :
  {
    "case.1" :
    {
      "scenario" : "this the case 1.",
      "result" : "this is a very long line which is not easily readble. \
                  so i would like to write it in multiple lines. \
                  but, i do NOT require any new lines in the output."
    }
  }
}

答案 5 :(得分:0)

这是作为编写器实现的,因为对于单个字符,可能存在多个输出字符。我无法想象这是读者。这个任务非常繁重,但可以扩展。

String multilineJson = "{\n" +
        "prop1 = \"value1\",\n" +
        "prop2 = \"multi line\n" +
        "value2\"\n" +
        "}\n";
String multilineJsonExpected = "{\n" +
        "prop1 = \"value1\",\n" +
        "prop2 = \"multi line\\nvalue2\"\n" +
        "}\n";

StringWriter sw = new StringWriter();
JsonProcessor jsonProcessor = new JsonProcessor(sw);
jsonProcessor.write(multilineJson);

assertEquals(multilineJsonExpected, sw.toString());

实施

public class JsonProcessor extends FilterWriter {

    private char[] curr;
    private int currIdx;

    private boolean doubleQuoted;

    public JsonProcessor(Writer out) {
        super(out);
    }

    @Override
    public void write(String str) throws IOException {
        char[] arr = str.toCharArray();
        write(arr, 0, arr.length);
    }

    @Override
    synchronized public void write(char[] cbuf, int off, int len) throws IOException {
        curr = Arrays.copyOfRange(cbuf, off, len - off);
        for (currIdx = 0; currIdx < curr.length; currIdx++) {
            processChar();
        }
    }

    private void processChar() throws IOException {
        switch (currentChar()) {
            case '"':
                processDoubleQuotesSymbol();
                break;
            case '\n':
            case '\r':
                processLineBreakSymbol();
                break;
            default:
                write(currentChar());
                break;
        }
    }

    private void processDoubleQuotesSymbol() throws IOException {
        doubleQuoted = !doubleQuoted;
        write('"');
    }

    private void processLineBreakSymbol() throws IOException {
        if (doubleQuoted) {
            write('\\');
            write('n');
            if (lookAhead() == '\n' || lookAhead() == '\r') {
                currIdx++;
            }
        } else {
            write(currentChar());
        }
    }

    private char currentChar() {
        return curr[currIdx];
    }

    private char lookAhead() {
        if (currIdx >= curr.length) {
            return 0;
        }
        return curr[currIdx + 1];
    }
}