[英]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”下),除非您知道確定這是一棵小樹。 如@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.