2013-05-03 22 views
5

mam do czynienia z systemami, które manipulują „zrelaksowany” danych JSON, który zawiera shell-styl # linię komentuje:tworzenie powłoki komentarze w stylu JSON

[ 
    { 
    # Batman 
    "first-name": "Bruce", 
    "last-name": "Wayne" 
    }, 
    { 
    # Superman 
    "first-name": "Clark", 
    "last-name": "Kent" 
    } 
] 

Część systemu pracuję nad zastosowaniami json-lib - co jest dla mnie zaskoczeniem odkryciem, jest tolerancyjny dla komentarzy w stylu powłoki - do przeanalizowania danych wejściowych JSON.

muszę wyodrębnić kilka dodatkowych adnotacji z tych uwag, ale json-lib wydaje się po prostu odrzucić je bez zapewniając API dla ich czytanie:

JSONObject map = (JSONObject)JSONSerializer.toJSON("{\n"+ 
                " # Batman\n" + // note the shell-style # comment 
                " \"first-name\": \"Bruce\",\n" + 
                " \"last-name\": \"Wayne\"\n" + 
                "}"); 
System.out.println(map.toString()); 
/* <<'OUTPUT' 
* {"first-name":"Bruce","last-name":"Wayne"} 
* OUTPUT 
* note the absence of the shell-style comment 
*/ 

Ma to sens, ponieważ komentarze nie są częścią Specyfikacja JSON i mam szczęście, json-lib nie dusi się, gdy parsuje je w pierwszej kolejności.

Z dopiskiem:

  • inne systemy zużywają tę samą JSON i adnotacje muszą być przejrzyste dla nich, więc struktura JSON nie mogą być modyfikowane przez dodanie właściwości komentarzach zamiast.
  • Nie wszystkie komponenty i obiekty w moim systemie mają dostęp do surowego źródła JSON: jeden komponent odczytuje plik i analizuje go za pomocą JSONlib i przekazuje zdesetyzowane mapy itp.

Jak mogę odczytać i przeanalizować te komentarze podczas przetwarzania danych wejściowych JSON? Czy istnieje biblioteka, która pozwoli mi je odczytać i powiązać z ich pozycją w JSON - czy mogę łatwo połączyć komentarz Batman do wpisu "Bruce Wayne"?

Obecnie używam json-lib, ale jestem otwarty na zbadanie innych bibliotek JSON i równie otwartych na używanie innych języków, które rozszerzają JSON, takich jak YAML - ale nie jestem pewien, czy te narzędzia pozwolą mi przeczytaj i przetwórz komentarze na moim wejściu.

+0

http://www.lifl.fr/~riquetd/parse-a-json-file-with-comments.html Ten link używa wyrażenia regularnego: ''(^)? [^ \ S \ n] */(?: \ * (. *?) \ */[^ \ S \ n] * |/[^ \ n] *) ($)? ', Aby usunąć komentarze. Oczywiście możesz użyć tego samego wyrażenia regularnego do innych celów. –

+0

@remyabel - Nie wszystkie komponenty i obiekty w moim systemie mają dostęp do surowego źródła JSON: jeden komponent odczytuje plik i analizuje go za pomocą JSONlib i przekazuje zdesetyzowane mapy itp. –

+2

zawsze możesz nie umieszczać sensownych danych w lokalizacji "wyrzucania"? tak jak nie przechowuję moich ważnych rzeczy w kosza na śmieci poza moim domem ... – jtahlborn

Odpowiedz

4

Co wybrałem zrobić, to zmodyfikować domenę publiczną bibliotekę JSON.org wspierać komentarzy powłoki i dodawanie komentarzy do obiektu JSON, co robiłem w tym GitHub GIST:

https://gist.github.com/peteroupc/5529464

Przykład użycia:

JSONObject obj=new JSONObject("{ # Comment\n"+ 
     "\"first-key\":\"first-value\",\n"+ 
     "\"second-key\":\"second-value\" }", 
     JSONObject.OPTION_SHELL_COMMENTS | // Support SHELL-style comments 
     JSONObject.OPTION_ADD_COMMENTS // Incorporate comments in the JSON object 
); 
System.out.println(obj); // Output the JSON object 

Przykładowe wyjście. Zauważ, że komentarz występuje w kluczu o nazwie "@comment".

{"second-key":"second-value","@comment":"Comment","first-key":"first-value"} 

Ale jednym z wymagań jest to, że „struktura JSON nie mogą być modyfikowane przez dodanie Właściwości za komentarze zamiast”. Oznacza to, że komentarze muszą być powiązane z obiektami JSON w inny sposób. Na szczęście specyfikacja JSON Pointer została niedawno opublikowana jako RFC 6901. Wskaźnik JSON jest ciągiem, który odnosi się do obiektu JSON w innym obiekcie JSON. W związku z tym wymagane są dodatkowe kroki: znajdź obiekty podrzędne za pomocą klawiszy "@comment", usuń klucze i stwórz mapowanie wskaźników JSON do komentarzy.

Zostało to zilustrowane poniższym kodem.

// Objects with comments associated with them will 
// now contain an "@comment" key; get the JSON Pointers 
// (RFC6901) to these objects and remove the "@comment" keys. 
Map<String,Object> pointers=JSONPointer.getPointersWithKeyAndRemove(obj,"@comment"); 
// For each JSON Pointer, get its corresponding object. 
// They will always be JSONObjects. 
for(String pointer : pointers.keySet()){ 
    JSONObject subobj=(JSONObject)JSONPointer.getObject(obj,pointer); 
    System.out.println(subobj); // Output the object 
    System.out.println(pointers.get(pointer)); // Output the key's value 
} 

Przykâadowa:

{"second-key":"second-value","first-key":"first-value"} 
Comment 

Od JSON Pointer jest nowy, napisałem własną implementację tego i włączyła ją w GIST GitHub.


Oto dalsze przykłady do wyjaśnienia.

Biorąc pod uwagę tę tablicę JSON (użyj JSONArray zamiast JSONObject w tym przykładzie):

[{ # foo 
"foo-key":"foo-value"}, 
{ # This is a 
# quite long comment. 
"bar-key":"bar-value"}] 

Wynik byłby:

{"foo-key":"foo-value"} 
foo 
{"bar-key":"bar-value"} 
This is a quite long comment. 

W rezultacie, wiele uwagi są połączyły w jednym komentarzu . Ale biorąc pod uwagę to JSON tablicy:

[{ # foo 
"foo-key":"foo-value"}, 
{ # This is a 
# quite long comment. 
"bar-key":"bar-value" 
# This is another comment. 
    }] 

Wynik byłby:

{"foo-key":"foo-value"} 
foo 
{"bar-key":"bar-value"} 
This is another comment. 

W rezultacie, wiele komentarzy, które pojawiły się w wielu miejscach na „bar” obiektu nie połączyły.

+0

Wystarczy sprawdzić, czy rozumiem: to pozwala tylko na jeden komentarz na obiekt? –

+0

Obecna implementacja łączy komentarze, które występują bezpośrednio obok siebie, ale nie komentarze, które występują w różnych miejscach tego samego pod-obiektu. Wyjaśnię to dokładniej na podstawie dalszych przykładów. –

+0

Czy możesz mi powiedzieć, czy to rozwiązanie działa dla Ciebie? –

0

inne systemy zużywają tę samą JSON i adnotacje muszą być przejrzyste dla nich, więc struktura JSON nie mogą być modyfikowane przez dodanie właściwości komentarzach zamiast

Korzystanie komentarze w wiadomościach przekazywanie danych między systemami nie wydaje się dobrą praktyką. . Na przykład. XML nie obsługuje tego.

Dlaczego po prostu nie uwzględnić ważnych "komentarzy" jako danych? Tak właśnie jest, jeśli drugi system go używa. : ^)

+0

"Używanie komentarzy w wiadomościach do przekazywania danych między systemami nie wydaje się dobrą praktyką." Zgoda. Jeśli chodzi o "jeśli drugi system go używa": to, co mam na myśli, "adnotacje muszą być dla nich przezroczyste" to to, że dane komentarza nie mogą znajdować się w JSON, to że nie można go dodać jako nowego klucza do obiektu JSON - wtedy inny system przetworzy adnotacje, których nie powinny. –

+0

Ah, rozumiem. Zatem komentarze nie są używane jako dane. Wszystko dobrze. :) –