解析一个非常复杂的嵌套json,其结构总是在JAVA中发生变化

时间:2014-07-07 16:26:37

标签: java json parsing

我有一个非常复杂的嵌套json,其结构总是在变化。我想在JAVA中解析它,以便我可以使用键/字段名称检索任何元素。

选项1 - 执行此操作的最简单方法是将json转换/解析为JAVA对象。 我已经尝试了所有东西(gson,JSONObject,Jackson ......)但我不能转换json,除非我有一个java类准备好,因为json没有遵循固定的结构我不能将它转换为JAVA类。有没有其他库可以将json转换为java对象? (无需预先存在的java类将json转换为)

选项2 - 或者是否有我可以使用的方法/库,如果给出了json的一部分,程序将打印json文件中的所有元素。像这样......

StreetAddressLine
PrimaryTownName : value
CountryISOAlpha2Code :value
TerritoryAbbreviatedName :value
PostalCode : value

{"PrimaryAddress": [        {
          "StreetAddressLine": [{"LineText": "492 Koller St"}],
          "PrimaryTownName": "San Francisco",
          "CountryISOAlpha2Code": "US",
          "TerritoryAbbreviatedName": "CA",
          "PostalCode": "94110",
          "AddressUsageTenureDetail": [{"TenureTypeText":           {
            "@DNBCodeValue": 1129,
            "$": "Rents"
          }}],
          "PremisesUsageDetail": [{"PremisesUsageFunctionDetail": [{"PremisesFunctionText":           {
            "@DNBCodeValue": 12058,
            "$": "Manufacturing"
          }}]}],
          "CountyOfficialName": "San Francisco County",
          "TerritoryOfficialName": "California",
          "CountryGroupName": "North America",
          "GeographicalPrecisionText":           {
            "@DNBCodeValue": 0,
            "$": "Unknown"
          },
          "UndeliverableIndicator": false,
          "MetropolitanStatisticalAreaUSCensusCode": ["San Francisco-Oakland-Hayward CA"],
          "RegisteredAddressIndicator": false,
          "ResidentialAddressIndicator": false
        }]}

非常感谢!

2 个答案:

答案 0 :(得分:3)

尝试使用json-simple将JSON解析为一堆嵌套的JSONObject(基本上是地图)和JSONArray(基本上是列表)元素并自行提取值。< / p>

只是一个节点:PrimaryAddress表示可能还有SecondaryAddress,因此嵌套不应该更改,否则可能很难确定StreetAddressLine所属的地址到。

在这种情况下,更好的问题是:为什么结构会经常发生变化?

答案 1 :(得分:1)

好的,我找到了解决方案!我使用了Jackson Parser

首先将jsonString映射到JsonNode

JsonNode rootNode = mapper.readValue(jsonString, JsonNode.class);

更新rootNode以包含所需密钥的json:

    rootNode = rootNode.findParent(key);

然后根据它是一个数组还是一个列表处理它分开:

if(rootNode.path(key).isArray()){
//key is the field in the json that you might be looking for
for (final JsonNode objNode : rootNode) {

     for (Iterator<String> keyArray = objNode.getFieldNames(); keyArray.hasNext();){

         fieldName = keyArray.next();

         fieldValue = objNode.path(fieldName).asText();                 
         if(fieldValue != ""){
             System.out.println(fieldName + " = " + fieldValue);

         }else{
             arrayHandler(objNode,fieldName);
         }
     }
 }

在每次迭代时检查生成的JsonNode是数组还是列表。 如果它是一个List处理它不同(只是迭代这样的键值对)

for (Iterator<String> keyArray = rootNode.getFieldNames(); keyArray.hasNext();){
        fieldName = keyArray.next();
        fieldValue = rootNode.get(fieldName).asText();
        System.out.println(fieldName + " = " + fieldValue);
    }

每次迭代后检查下一个jsonNode是什么,并递归地调用相应的处理程序......