web-dev-qa-db-ja.com

JSON値に複数行の文字列を含めることができますか

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"
    }
  }
}
101
user2409155

仕様 ! JSON文法のchar生成は、次の値を取ることができます。

  • any-Unicode-character-except -"- or -\- or-control-character
  • \"
  • \\
  • \/
  • \b
  • \f
  • \n
  • \r
  • \t
  • \u4桁の16進数

改行は「制御文字」なので、いいえ、文字列内にリテラルの改行を含めることはできません。ただし、必要な\n\rの任意の組み合わせを使用してエンコードできます。

JSONLint ツールは、JSONが無効であることを確認します。


更新:そして、実際にデータに改行を含めずにJSON構文内に改行を書きたい場合は、2倍も運が悪いです。 JSONはある程度人間に優しいことを目的としていますが、それでもdataであり、そのデータに任意のフォーマットを適用しようとしています。これは、JSONの目的とはまったく異なります。

正確な要件はわかりませんが、「読みやすさ」を改善するための解決策の1つは、配列として保存することです。

{
  "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(" ")
26
Brian McAuliffe

あまり良い解決策ではありませんが、hjsonツールを試すことができます。 リンク 。エディターで複数行のテキストを作成し、適切な有効なJSON形式に変換できます。 注:新しい行に「\ n」文字を追加しますが、「すべて置換」を使用してテキストエディタで簡単に削除できます。関数。

追伸質問へのコメントである必要がありますが、十分なレポを持っていません、ごめんなさい。

4
CodeMonkey

私が理解できるように、質問はjsonを使用して制御記号を含む文字列を渡す方法ではなく、エディター制御記号で文字列を分割できるファイルにjsonを保存および復元する方法についてです。

複数行の文字列をファイルに保存する場合、ファイルには有効なjsonオブジェクトが保存されません。ただし、プログラムでのみjsonファイルを使用する場合は、データを必要に応じて保存し、プログラムにロードしてjsonパーサーに渡すたびに、ファイルからすべての改行を手動で削除できます。

または、より良い方法として、必要に応じてスティングを編集するjsonデータソースファイルを作成し、プログラムで有効なjsonファイルへのユーティリティを使用してすべての新しい行を削除することもできます。使用します。

3

私はあなたが使用している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."
    }
  }
}
1
Elric Best

これは、単一の文字に対して複数の出力文字が存在する可能性があるため、ライターとして実装されます。これを読者として想像することはできませんでした。タスクにはかなり重いですが、かなり拡張可能です。

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];
    }
}
0