2013-05-22 2 views
74

Sto scrivendo un file JSON che verrebbe letto da un programma Java. Il frammento è il seguente ...Un valore JSON può contenere una stringa multilinea

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

possibile duplicato di [stringhe su più righe in JSON] (http: // StackOverflow .com/questions/2392766/multiline-strings-in-json) –

+9

Penso che si tratti più della leggibilità del file JSON serializzato e di _non_ sugli interruzioni di riga nei dati caricati (quindi, non un duplicato di [Stringhe multilinea in JSON] (http://stackoverflow.com/q/2392766/703040)). Pensa a qualcosa di più come usare JSON come file di configurazione in cui hai una lunga stringa e, per la leggibilità, è utile avvolgere la stringa nel caso qualcuno la stia modificando tramite un editor di testo. – zashu

risposta

41

Check out the specification! char produzione del grammatica JSON può assumere i seguenti valori:

  • -Unicode-carattere-except- qualsiasi " oppure \ -o-control-personaggio
  • \"
  • \\
  • \/
  • \b
  • \f
  • \n
  • \r
  • \t
  • \uquattro cifre esadecimali

Newlines sono "caratteri di controllo", così, no, non possono avere un ritorno a capo letterale all'interno la tua corda. Tuttavia è possibile codificarlo utilizzando qualsiasi combinazione di \n e \r richiesta.

Lo strumento JSONLint conferma che il proprio JSON non è valido.


Aggiornamento: E se si desidera scrivere a capo all'interno della vostra sintassi JSON senza realmente includendo i fine riga nei dati, allora sei anche doppiamente fuori di fortuna. Mentre JSON è destinato ad essere umano-grado in misura, è ancora dati e stai cercando di applicare la formattazione arbitraria a quei dati. Questo non è assolutamente ciò di cui parla JSON.

3

Come ho potuto capire la domanda non riguarda come passare una stringa con i simboli di controllo utilizzando json ma come archiviare e ripristinare JSON nel file in cui è possibile dividere una stringa con i simboli di controllo dell'editor.

Se si desidera memorizzare una stringa multilinea in un file, il file non memorizzerà l'oggetto valido json. Tuttavia, se si utilizzano i file solo nel proprio programma, è possibile memorizzare i dati come desiderato e rimuovere manualmente tutti i newline dal file ogni volta che lo si carica nel programma e quindi passare a parser json.

O, in alternativa, che sarebbe meglio, si può avere il file di origine di dati json in cui si modifica un pungiglione come si desidera e quindi rimuovere tutte le nuove linee con una certa utilità per il file valido json che utilizzerà il vostro programma.

23

Non sono sicuro del vostro esatto requisito ma una possibile soluzione per migliorare la "leggibilità" è archiviarla come array.

{ 
    "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."] 
    } 
    } 
} 

} 

Il unirsi nuovamente quando richiesto con

result.join(" ") 
+4

Questo è tuttavia non banale. È una perdita di astrazione. Prenderò in considerazione un formato di dati specificato in questo modo per essere, in sostanza, rotto. –

+3

Non riesco a immaginare di progettare un documento API o JSON in questo modo solo per aumentare la leggibilità delle stringhe (solo per motivi di debug, suppongo): | .... –

+0

Utile per descrizioni comunque, grazie! – Rob

0

Questo è implementato come scrittore perché per il singolo carattere ci potrebbe essere più charactes uscita. Non potrei immaginarlo come lettore. Abbastanza pesante per il compito ma piuttosto estensibile.

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()); 

Attuazione

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

Non abbastanza buona soluzione, ma si può provare lo strumento hjson. Link. Ti consente di scrivere testo in più righe nell'editor e di convertirlo nel formato JSON valido appropriato. Nota: aggiunge '\ n' caratteri per le nuove linee, ma è possibile semplicemente eliminarli in qualsiasi editor di testo con la funzione "Sostituisci tutto ..".

P.S. Dovrebbe essere un commento alla domanda, ma non avere abbastanza pronti contro termine, mi dispiace.

1

credo che dipende da cosa interprete JSON stai usando ... in parole povere javascript si potrebbe usare terminatori di linea

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

Questo è corretto, ma verranno visualizzati spazi di indentazione: 'a \ c' =>' a c'. –