簡體   English   中英

Java FastXML JSON庫:如何解析嵌套的JSON結構

[英]Java FastXML JSON library: How to parse a nested JSON structure

下面是我正在嘗試以流方式使用org.fasterxml.jackson.core和jackson-databind庫測試JSON處理的Java程序。

目的是學習如何處理JSON並捕獲所需的信息。 現在,我要完成以下任務:
1)我在這里發布的JSON有很多數據。 遵循此JSON的Java程序是我嘗試處理此JSON的嘗試,尤其是捕獲“ part1 / myAnalysis / matches“ name”:US SSN元素以及“ name”:MasterCard Credit Card number ,兩者元素屬於“ part1 / myAnalysis / matches ”的范圍。

好的,現在,我的目標是: 我只希望我的程序進行編譯並至少打印出我感興趣的兩個元素(上述元素)

我的編譯嘗試產生以下結果:

Unprocessed property: type
Unprocessed property: incidentTimestamp
Unprocessed property: numOfMatches
Unprocessed property: myReport
Unprocessed property: whatSetItOffEntry
Unprocessed property: seeRestrictedIds
Unprocessed property: status
Unprocessed property: timeStamps
Unprocessed property: count

因此,程序正在嘗試處理的JSON如下。 如果有人可以指出如何使該程序編譯,然后打印出我想要的元素。 這將是一個很棒的兩步過程Task。

 { "type": "ImportantIncidentInfo", "incidentTimestamp": "2014-05-15T10:09:27.989-05:00", "numOfMatches": 4, "myReport": { "docReports": { "part1/.": { "path": [ "unknown" ], "myAnalysis": { "matches": [ { "id": { "major": 1, "minor": 0 }, "name": "US SSN", "position": 13, "string": " 636-12-4567 " }, { "id": { "major": 3, "minor": 0 }, "name": "MasterCard Credit Card Number", "position": 35, "string": " 5424-1813-6924-3685 " } ] }, "cleanedUpData": [ { "startPosition": 0, "endPosition": 65, "frameContent": "" } ], "minedMetadata": { "Content-Encoding": "ISO-8859-1", "Content-Type": "text/html; charset=iso-8859-1" }, "deducedMetadata": { "Content-Type": "text/html; iso-8859-1" } }, "part2/.": { "path": [ "unknown" ], "patternAnalysis": { "matches": [ { "id": { "major": 1, "minor": 0 }, "name": "SSN", "position": 3, "string": " 636-12-4567\\r" }, { "id": { "major": 3, "minor": 0 }, "name": "MasterCard Credit Card Number", "position": 18, "string": "\\n5424-1813-6924-3685\\r" } ] }, "cleanedUpData": [ { "startPosition": 0, "endPosition": 44, "frameContent": "" } ], "minedMetadata": { "Content-Encoding": "windows-1252", "Content-Type": "text/plain; charset=windows-1252" }, "deducedMetadata": { "Content-Type": "text/plain; iso-8859-1" } } } }, "whatSetItOffEntry": { "action": "Log", "component": { "type": "aComponent", "components": [ { "type": "PatternComponent", "patterns": [ 1 ], "not": false } ], "not": false }, "ticketInfo": { "createIncident": true, "tags": [], "seeRestrictedIds": [ { "type": "userGroup", "name": "SiteMasters", "description": "Group for SiteMasters", "masters": [ "04fb02a2bc0fba" ], "members": [], "id": "04fade" } ] }, "letmeknowInfo": { "createNotification": true, "contactNames": [ "someguy@gmail.com" ] } }, "seeRestrictedIds": [ "04fade66c0" ], "status": "New", "timeStamps": [ "2014-03-15T10:09:27.989-05:00" ], "count": 1 } 

任務2
2)為了處理此JSON,我編寫了以下Java程序。

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.core.*;

import java.io.*;

public class ParseJson {

    public static void main(String[] args) {

        try{

                // TODO Auto-generated method stub
                JsonFactory f = new MappingJsonFactory();
                //JsonParser jp = f.createJsonParser(new File(args[0]));
                JsonParser jp = f.createParser(new File("C:/somepath /in/my/eclipse/project/jsonFormattedModified.json"));


                JsonToken current;

                current = jp.nextToken();
                if (current != JsonToken.START_OBJECT) {
                  System.out.println("Error: root should be object: quiting.");
                  return;
                }

                while (jp.nextToken() != JsonToken.END_OBJECT) {
                  String fieldName = jp.getCurrentName();
                  // move from field name to field value
                  current = jp.nextToken();
                  if (fieldName.equals("matches")) {
                    if (current == JsonToken.START_ARRAY) {
                      // For each of the records in the array
                      while (jp.nextToken() != JsonToken.END_ARRAY) {
                        // read the record into a tree model,
                        // this moves the parsing position to the end of it
                        JsonNode node = jp.readValueAsTree();
                        // And now we have random access to everything in the object
                        System.out.println("Name: " + node.get("name").asText());
                        System.out.println("POS: " + node.get("pos").asText());
                      }
                    } else {
                      System.out.println("Error: records should be an array: skipping.");
                      jp.skipChildren();
                    }
                  } else {
                    System.out.println("Unprocessed property: " + fieldName);
                    jp.skipChildren();
                  }
                }                
              } catch(IOException ie) {
                  ie.printStackTrace();

              } 

        }
}

感謝您的所有幫助。

我建議您使用非常有用的Google API Gson輕松處理序列化和反序列化。 因此,首先,創建與您的json結構匹配的所有下面的類。

助手類:

class Helper {
    String type;
    String incidentTimestamp;
    int numOfMatches;
    Report myReport;
    WhatSetItOffEntry whatSetItOffEntry;
    List<String> seeRestrictedIds;
    String status;
    List<String> timeStamps;
    int count;
    //getters and setters
}

報告類別:

class Report {
    DocsReport docReports;
    //getters and setters
}

DocsReport類:

class DocsReport {
    @SerializedName("part1/.")
    Part1 part1;
    Part2 part2;
    //getters and setters
}

第一部分:

class Part1 {
    List<String> path;
    Analysis myAnalysis;
    List<CleanedUpData> cleanedUpData;
    MinedMetadata minedMetadata;
    DeducedMetadata deducedMetadata;
    //getters and setters
}

分析類:

class Analysis {
    List<Information> matches;
    //getters and setters
}

信息類:

class Information {
    Identifying id;
    String name;
    int position;
    String string;
    //getters and setters
}

識別類別:

class Identifying {
    int major;
    int minor;
    //getters and setters
}

CleanedUpData類:

class CleanedUpData {
    int startPosition;
    int endPosition;
    String frameContent;
    //getters and setters
}

MinedMetadata類:

class MinedMetadata {
    @SerializedName("Content-Encoding")
    String contentEncoding;
    @SerializedName("Content-Type")
    String contentType;
    //getters and setters
}

DeducedMetadata類:

class DeducedMetadata {
    @SerializedName("Content-Type")
    String contentType;
    //getters and setters
}

Part2類:

class Part2 {
    List<String> path;
    Analysis patternAnalysis;
    CleanedUpData cleanedUpData;
    MinedMetadata minedMetadata;
    DeducedMetadata deducedMetadata;
    //getters and setters
}

WhatSetItOffEntry類:

class WhatSetItOffEntry {
    String action;
    Component component;
    TicketInfo ticketInfo;
    LetmeknowInfo letmeknowInfo;
    //getters and setters
}

組件類:

class Component {
    String type;
    List<ComponentData> components;
    Boolean not;
    //getters and setters
}

ComponentData類:

class ComponentData {
    String type;
    List<Integer> patterns;
    Boolean not;
    //getters and setters
}

TicketInfo類:

class TicketInfo {
    Boolean createIncident;
    List<Object> tags;
    List<RestrictedIds> seeRestrictedIds;
    //getters and setters
}

RestrictedIds類:

class RestrictedIds {
    String type;
    String name;
    String description;
    List<String> masters;
    List<Object> members;
    String id;
    //getters and setters
}

LetmeknowInfo類:

class LetmeknowInfo {
    Boolean createNotification;
    List<String> contactNames;
    //getters and setters
}

然后得到你的兩個名字如下

Gson gson = new Gson();
Helper data = gson
        .fromJson(
               new BufferedReader(
                        new FileReader(
                                "C:/somepath/in/my/eclipse/project/jsonFormattedModified.json")),
                new TypeToken<Helper>() {
                }.getType());

String name1 = data.getMyReport().getDocReports().getPart1()
        .getMyAnalysis().getMatches().get(0).getName();
String name2 = data.getMyReport().getDocReports().getPart1()
        .getMyAnalysis().getMatches().get(1).getName();

System.out.println(name1+"\n"+name2);

輸出:

US SSN
MasterCard Credit Card Number

要考慮的兩件事:

  • 如果要保持流式傳輸,則調用jp.readValueAsTree()並不是一個好主意,因為它將分配內存以創建包含當前節點下所有數據的樹(在您的代碼中,所有內容均在“ matches”下),除非您知道確定這是一棵小樹。
  • 要獲得數組中的值,無需先創建數組。 流式API使您可以遍歷所需數組中的值。

如@MChaker在他的答案中所示,如果您需要JSON文件中提供的大多數數據,則創建一個模型來保存數據將是有益的。 但是,如果您只需要幾個價值觀,傑克遜就會讓您做到這一點。 盡管如此,我必須承認,以真正的流方式獲取數據將需要一定的創造力,以找到跟蹤您的位置以及期望的數據的方式。

以下代碼顯示了簡單的方法和流式傳輸方法:

import java.io.*;
import java.util.*;

import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;

/**
 * http://stackoverflow.com/q/30288878/3080094
 * Using jackson-databind-2.5.3 which uses
 * jackson-annotations-2.5.0 and
 * jackson-core-2.5.3
 * @author vanOekel
 */
public class JsonTest {

    public static void main(String[] args) {

        try {
            new JsonTest().getNames();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    ObjectMapper jsonMapper = new ObjectMapper();
    JsonFactory jsonFactory = new JsonFactory();

    void getNames() throws Exception {

        final String resourceName = "some.json";
        JsonNode jn;
        try (InputStream in = 
                Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceName)
                ) {
            if (in == null) {
                throw new FileNotFoundException("File not found: " + resourceName);
            }
            jn = jsonMapper.readTree(in);
        } 
        findByPath(jn);

        try (InputStream in = 
                Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceName)
                ) {
            if (in == null) {
                throw new FileNotFoundException("File not found: " + resourceName);
            }
            JsonParser jsonParser = jsonFactory.createParser(in);
            findInStream(jsonParser);
        } 
    }

    final String[] path = new String[] {"myReport", "docReports", "part1/.", "myAnalysis", "matches", "name"};

    void findByPath(JsonNode jn) {

        JsonNode matchesNamesNode = jn;
        for (int i = 0; i < path.length - 1; i++) {
            matchesNamesNode = matchesNamesNode.path(path[i]);
        }
        if (matchesNamesNode.isMissingNode()) {
            throw new RuntimeException("No node with names found.");
        }
        System.out.println("Tree names: " + matchesNamesNode.findValuesAsText(path[path.length - 1]));
    }

    void findInStream(JsonParser jp) throws Exception {

        int pathIndex = 0;
        List<String> names = new ArrayList<String>();
        boolean breakOnClose = false;

        while (jp.nextToken() != null) {
            final String fieldName = jp.getCurrentName();
            if (fieldName == null) {
                continue;
            }
            if (breakOnClose && fieldName.equals(path[path.length - 2])) {
                System.out.println("Stopping search at end of node " + fieldName);
                break;
            }
            if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
                continue;
            }
            // System.out.println("Field " + fieldName);
            if (pathIndex >= path.length - 1) {
                if (fieldName.equals(path[path.length - 1])) {
                    // move from field name to field value.
                    jp.nextToken(); 
                    String name = jp.getValueAsString();
                    if (name == null) {
                        throw new RuntimeException("No value exists for field " + fieldName);
                    }
                    names.add(name);
                    System.out.println("Found " + fieldName + " value: " + name);
                }
            } else if (fieldName.equals(path[pathIndex])) {
                System.out.println("Found node " + path[pathIndex]);
                pathIndex++;
                if (pathIndex >= path.length - 1) {
                    System.out.println("Looking for names ...");
                    breakOnClose = true;
                    // prevent breaking on "matches" value json-token.
                    jp.nextFieldName(); 
                }
            }
        }
        System.out.println("Streaming names: " + names);
    }

}
  String jsonRecord = "[
                 {
                   a:a,
                   b:
                     {
                      c:
                        [{d:d,e:e},{d:d1,e:e1}]
                     }
                  }
                ]";
 String value ="$.b.c[1].d";
 String str = JsonPath.read(jsonRecord, value);
 system.out.println(str);

它將打印d1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM