2013-05-22 4 views
74

Я пишу файл 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" 
    } 
    } 
} 
+0

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

+2

возможно дубликат [строк Multiline в JSON] (HTTP: // StackOverflow .com/questions/2392766/multiline-strings-in-json) –

+9

Я думаю, что это больше касается читаемости сериализованного файла JSON и _not_ о разрыве строк в загруженных данных (таким образом, это не дубликат [Многострочные строки в JSON] (http://stackoverflow.com/q/2392766/703040)). Подумайте об этом скорее как использование JSON в качестве файла конфигурации, где у вас длинная строка, и для удобства чтения полезно обернуть строку, если кто-то ее редактирует с помощью текстового редактора. – zashu

ответ

41

Отъезд the specification! голец производство грамматике JSON может принимать следующие значения:

  • любой-Unicode-символов except- " -или- \ -или-контроль символов
  • \"
  • \\
  • \/
  • \b
  • \f
  • \n
  • \r
  • \t
  • \uчетыре-гекс-цифры

Newlines являются "управляющие символы" так, нет, вы не можете иметь буквальный перевод строки в ваша строка. Однако вы можете кодировать его, используя любую комбинацию \n и \r, которые вам нужны.

Инструмент JSONLint подтверждает, что ваш JSON недействителен.


Update: И если вы хотите, чтобы написать новые строки внутри вашего синтаксиса JSON фактически не включая символы новой строки в данных, то вы даже вдвойне повезло. В то время как JSON призван быть в некоторой степени дружественным к человеку, все равно данные, и вы пытаетесь применить произвольное форматирование к этим данным. Это совсем не то, о чем JSON.

3

Как я понял, вопрос заключается не в том, как передать строку с управляющими символами, используя json, но как сохранить и восстановить json в файле, где вы можете разделить строку с символами управления редактором.

Если вы хотите сохранить многострочную строку в файле, то ваш файл не сохранит действительный объект json. Но если вы используете только файлы json только в своей программе, вы можете хранить данные по своему усмотрению и удалять все строки новой строки из файла вручную каждый раз, когда вы загружаете его в свою программу, а затем передаете в json parser.

Или, как вариант, который будет лучше, вы можете иметь исходные файлы json данных, где вы редактируете жало, как вы хотите, а затем удалите все новые линии с некоторой полезностью для действительного json файла, который программа будет использовать.

23

Я не уверен в ваших точных требованиях, но одним из возможных решений для улучшения «удобочитаемости» является сохранение его в виде массива.

{ 
    "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(" ") 
+4

Это неэмпактно. Это абстракция. Я бы счел, что формат данных, указанный таким образом, будет, по сути, нарушен. –

+3

Я не могу представить себе проект API или JSON таким образом, чтобы увеличить удобочитаемость строк (только для аргументов отладки, которые я предполагаю): | .... –

+0

Полезно для описания однако, спасибо! – Rob

0

Это реализуется как писатель, потому что для одного символа не может быть несколько выходных charactes. Я не мог представить это как читателя. Довольно тяжелая задача, но довольно расширяемая.

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

не очень хорошее решение, но вы можете попробовать инструмент hjson. Link. Это позволяет вам писать текстовые многострочные в редакторе, а затем преобразовывать их в правильный действующий формат JSON. Примечание: добавляет символы '\ n' для новых строк, но вы можете просто удалить их в любом текстовом редакторе с помощью функции «Заменить все ..».

P.S. Должен быть комментарий к вопросу, но не хватает репо, извините.

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." 
    } 
    } 
} 
+0

Это правильно, но выпадающие пробелы выдают: 'a \ c' =>' a c'. –

Смежные вопросы