简体   繁体   English

您如何解析名称中带有冒号的 JSON? 安卓/Java

[英]How do you parse JSON with a colon in the name? Android/Java

For example: { "primary:title":"Little Red Riding Hood"}例如: { "primary:title":"Little Red Riding Hood"}

My Parser in Java (Android) is always getting stuck because of the colon between primary and title.由于主要和标题之间的冒号,我的 Java (Android) 解析器总是卡住。 I can parse anything else with ease, I just need help in this.我可以轻松解析任何其他内容,我只需要这方面的帮助。

public class MainActivity extends Activity {
    /** Called when the activity is first created. */

    TextView txtViewParsedValue;

    private JSONObject jsonObject;
    private JSONArray jsonArray;

    String [] titles, links, mediaDescriptions, mediaCredits, descriptions, dcCreators, pubDates, categories;
    String [] permalinks, texts;            // guid
    String [] rels, hrefs;
    String [] urls, media, heights, widths; // media:content

    String strParsedValue = "";

    private String strJSONValue;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        strJSONValue = readRawTextFile(this, R.raw.jsonextract);

        txtViewParsedValue = (TextView) findViewById(R.id.text_view_1);

        try {
            parseJSON();

        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void parseJSON() throws JSONException
    {
        txtViewParsedValue.setText("Parse 1");

        jsonObject = new JSONObject(strJSONValue);
        jsonArray = jsonObject.getJSONArray("item");

        titles = new String[jsonArray.length()];
        links = new String[jsonArray.length()];
        permalinks = new String[jsonArray.length()];
        texts = new String[jsonArray.length()];
        mediaDescriptions = new String[jsonArray.length()];
        mediaCredits = new String[jsonArray.length()];
        descriptions = new String[jsonArray.length()];
        dcCreators = new String[jsonArray.length()];
        pubDates = new String[jsonArray.length()];
        categories = new String[jsonArray.length()];

        txtViewParsedValue.setText("Parse 2");

        for (int i=0; i<jsonArray.length(); i++)
        {
            JSONObject object = jsonArray.getJSONObject(i);

            titles[i] = object.getString("title");
            links[i] = object.getString("link");

            JSONObject guidObj = object.getJSONObject("guid");
            permalinks[i] = guidObj.getString("isPermaLink");
            texts[i] = guidObj.getString("text");
            //mediaDescriptions[i] = object.getString("media:description");
            //mediaCredits[i] = object.getString("media:credit");

                // *** THE PARSER FAILS IF THE COMMENTED LINES ARE IMPLEMENTED BECAUSE
                // OF THE : IN BETWEEN THE NAMES ***

            descriptions[i] = object.getString("description");
            //dcCreators[i] = object.getString("dc:creator");
            pubDates[i] = object.getString("pubDate");
            categories[i] = object.getString("category");   
        }



        for (int i=0; i<jsonArray.length(); i++)
        {
            strParsedValue += "\nTitle: " + titles[i];
            strParsedValue += "\nLink: " + links[i];
            strParsedValue += "\nPermalink: " + permalinks[i];
            strParsedValue += "\nText: " + texts[i];
            strParsedValue += "\nMedia Description: " + mediaDescriptions[i];
            strParsedValue += "\nMedia Credit: " + mediaCredits[i];
            strParsedValue += "\nDescription: " + descriptions[i];
            strParsedValue += "\nDC Creator: " + dcCreators[i];
            strParsedValue += "\nPublication Date: " + pubDates[i];
            strParsedValue += "\nCategory: " + categories[i];
            strParsedValue += "\n";
        }


        txtViewParsedValue.setText(strParsedValue);
    }

    public static String readRawTextFile(Context ctx, int resId)
    {
         InputStream inputStream = ctx.getResources().openRawResource(resId);

            InputStreamReader inputreader = new InputStreamReader(inputStream);
            BufferedReader buffreader = new BufferedReader(inputreader);
             String line;
             StringBuilder text = new StringBuilder();

             try {
               while (( line = buffreader.readLine()) != null) {
                   text.append(line);
                   //text.append('\n');
                 }
           } catch (IOException e) {
               return null;
           }
             return text.toString();
    }

For one, and to answer your question, there is no issue with JSONObject and the org.json.* classes parsing keys with colons in them if they're properly formed.一方面,为了回答您的问题,JSONObject 和 org.json.* 类没有问题,如果它们格式正确,则解析其中带有冒号的键。 The following unit test passed which means it was able to parse your example scenario:以下单元测试通过,这意味着它能够解析您的示例场景:

public void testParsingKeysWithColons() throws JSONException {
    String raw = "{ \"primary:title\":\"Little Red Riding Hood\"}";
    JSONObject obj = new JSONObject(raw);
    String primaryTitle = obj.getString("primary:title");
    assertEquals("Little Red Riding Hood", primaryTitle);
}

Another suggestion is that using arrays of Strings for your data is clumsy and you'd be much better organized using a data structure to represent your objects.另一个建议是,将字符串数组用于数据是笨拙的,使用数据结构来表示对象会更好地组织起来。 Instead of string arrays for titles, links, descriptions;而不是标题、链接、描述的字符串数组; use an object that has these properties and make a list of the objects.使用具有这些属性的对象并列出这些对象。 For example:例如:

public class MyDataStructure {

    public String title;
    public String primaryTitle;
    public String link;
    public String mediaDescription;

    public static class Keys {
        public static String title = "title";
        public static String primaryTitle = "primary:title";
        public static String link = "link";
        public static String mediaDescription = "media:description";
    }

}

And then you can make a "translator" class that does all the parsing for you and returns a list of your object.然后你可以创建一个“翻译器”类,为你做所有的解析并返回你的对象列表。 This is much easier to work with and keep track of.这更容易使用和跟踪。 You never have to think about data misaligning or having more or less data in one of your arrays than you expected.您永远不必考虑数据未对齐或其中一个阵列中的数据比您预期的多或少。 You also have a much easier time testing where the problem is if your input data is missing anything or any of your json is malformed.如果您的输入数据丢失任何内容或任何 json 格式错误,您也可以更轻松地测试问题出在哪里。

public class MyDataStructureTranslator {

    public static List<MyDataStructure> parseJson(String rawJsonData) throws JSONException {

        List<MyDataStructure> list = new ArrayList<MyDataStructure>();
        JSONObject obj = new JSONObject(rawJsonData);
        JSONArray arr = obj.getJSONArray("item");

        for(int i = 0; i < arr.length(); i++) {
            JSONObject current = arr.getJSONObject(i);
            MyDataStructure item = new MyDataStructure();
            item.title = current.getString(MyDataStructure.Keys.title);
            item.primaryTitle = current.getString(MyDataStructure.Keys.primaryTitle);
            item.link = current.getString(MyDataStructure.Keys.link);
            item.mediaDescription = current.getString(MyDataStructure.Keys.mediaDescription);
            list.add(item);
        }

        return list;
    }

}

Since Java identifiers cannot have colons, just specify a json property name that maps to the exact json name like:由于 Java 标识符不能有冒号,因此只需指定一个映射到确切 json 名称的 json 属性名称,例如:

@JsonProperty("primary:title")
public String primaryTitle;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM