Подпрограмма Java для разделения текста JSON на строки в символах - PullRequest
0 голосов
/ 23 октября 2019

Допустим, мое приложение должно создать текстовый файл JSON в этой форме

{
 "key1"
:
"value1"
,
"key2"
:
"value2"
,
"arrayKey"
:
[
{
"keyA"
:
"valueA"
,
"keyB"
:
"valueB"
,
"keyC"
:
[
0
,
1
,
2
]
}
]
}

из

JSONObject.toString()

, который представляет собой одну длинную строку текста в моем приложении Java для Android

{"key1":"value1","key2":"value2","arrayKey":[{"keyA":"valueA","keyB":"valueB","keyC":[0,1,2]}]}

Было доказано, что подход регулярных выражений не работает.

Есть много подводных камней.

Поэтому я решил создать свой собственный парсер, чтобы выполнить работу

Редактировать: Внимание! В следующем коде есть ошибка, из-за которой экранированные кавычки рассматриваются как нормальные , см. Мой самый ответ на этот вопрос (также с дальнейшим улучшением)

public static String JSONTextToCRSeparatedJSONText(String JSONText)
{
    String result="";
    String symbolList="{}[]:,";
    char ch;
    char previousChar=0;

    int charNum=JSONText.length();
    boolean inRegion=false;
    boolean insertedBefore=false;
    char startRegionChar=0;
    for (int i=0;i<charNum;i++)
    {

    ch=JSONText.charAt(i);
    previousChar=ch; // mistake here, should be after the conditional statements, please see my answer with new code version


    if (!inRegion) 
    {
        if (((ch=='\"')||(ch=='\''))&&(previousChar!='\\'))
        {
            inRegion=true;
            startRegionChar=ch;
        }
    } else
    {
        if ((ch==startRegionChar)&&(previousChar!='\\'))
        {
            inRegion=false;

        }
    }

    if ((!inRegion)&& (symbolList.indexOf(ch)>-1)&&(!insertedBefore))
    {
        result=result+"\n";
    } 
    result=result+ch;
    insertedBefore=false; 
    if ((!inRegion)&& (symbolList.indexOf(ch)>-1))
    {
        result=result+"\n";
        insertedBefore=true; //it will be useful next iteration

    }
}
    return result;
}

Кажется, он работает.

Просто хотелось бы узнать

, все ли символы, которые он проверяет для вставки управляющего символа \ n, являются ли все символы возможными в тексте JSON

и существуют ли подводные камничто я не могу видеть.

Ответы [ 2 ]

0 голосов
/ 24 октября 2019

Код в вопросе неверен, потому что

previousChar=ch;

будет текущим символом, а не предыдущим, поэтому его нужно ставить после условных операторов.

Правильный код следующий (также он упрощен и не создает нежелательных строк):

public static String JSONTextToLineSeparatedJSONText(String JSONText)
{
    String result="";
    String symbolList="{}[]:,";
    char ch;
    char previousChar=0;

    int charNum=JSONText.length();
    boolean inRegion=false;
    boolean insertedBefore=false;
    char startRegionChar=0;
    for (int i=0;i<charNum;i++)
    {

    ch=JSONText.charAt(i);



    if (!inRegion) 
    {
        if (((ch=='\"')||(ch=='\''))&&(previousChar!='\\'))
        {
            inRegion=true;
            startRegionChar=ch;
        }
    } else
    {
        if ((ch==startRegionChar)&&(previousChar!='\\'))
        {
            inRegion=false;

        }
    }
    previousChar=ch; 

    if ((!inRegion)&& (symbolList.indexOf(ch)>-1)&&(!insertedBefore))
    {
       if (i>0) result=result+"\n";
    } 
    result=result+ch;
    insertedBefore=false; 
    if ((!inRegion)&& (symbolList.indexOf(ch)>-1))
    {
        result=result+"\n";
        insertedBefore=true; //it will be useful next iteration

    }
}
    return result;
}
0 голосов
/ 23 октября 2019

Я думаю, что вы делаете слишком много работы самостоятельно. На сегодняшний день существует две основные известные библиотеки, которые используются для работы с JSON. Одним из них является Jackson-JSON (также известный как «Быстрый XML» - иди на цифру ...), а другим - GSON - библиотека Google, основанная на Jackson-JSON, но также поддерживающая передачу двоичных объектов. Я лично предпочитаю Джексона-JSON, но это вопрос личных предпочтений. Для библиотеки GSON посмотрите здесь . Для Джексона посмотрите здесь . Для артефактов Maven для Джексона смотрите здесь . Если вы решите работать с Джексоном, то основным классом, который вам нужен, будет ObjectMapper . Начните с изучения методов readValue() и writeValue(). Ищите в Интернете бесконечные примеры того, как с ним работать. Это должно дать вам хорошее начало.

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

  String content = new String(Files.readAllBytes(resource.toPath()));

    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    JsonParser jp = new JsonParser();
    JsonElement je = jp.parse(content);
    String prettyJsonString = gson.toJson(je);
    System.out.println(prettyJsonString);

    return prettyJsonString;

Для Jackson-JSON:

  ObjectMapper mapper = new ObjectMapper();
    mapper.enable(SerializationFeature.INDENT_OUTPUT);
    String prettyJsonString = mapper.writeValueAsString(content);

    return prettyJsonString;

Намного меньше работы, чем вы сделали, и гораздо лучше проверено. Кроме того, если вы хотите представить такое же форматирование в Html, посмотрите ответ на этот вопрос: Довольно печать для JSON в JAVA отлично работает для консоли, но в браузере она не работает

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...