首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用jsonPath在不同级别的jsonfile中选择字段?

如何使用jsonPath在不同级别的jsonfile中选择字段?
EN

Stack Overflow用户
提问于 2020-05-12 13:47:19
回答 1查看 482关注 0票数 0

我想把jsonobjcts转换成csv文件。到目前为止,Wy ( rows )尝试将json文件作为一个JSONObject (从googlecode.josn-简单库)加载,然后用jsonPath将它们转换成一个字符串数组,然后用于构建csv行。然而,我正面临着jsonPath的一个问题。从给定的例子来看.

代码语言:javascript
运行
复制
{
"issues": [
    {
        "key": "abc",
        "fields": {
            "issuetype": {
                "name": "Bug",
                "id": "1",
                "subtask": false
            },
            "priority": {
                "name": "Major",
                "id": "3"
            },
            "created": "2020-5-11",
            "status": {
                "name": "OPEN"
            }
        }
    },
    {
        "key": "def",
        "fields": {
            "issuetype": {
                "name": "Info",
                "id": "5",
                "subtask": false
            },
            "priority": {
                "name": "Minor",
                "id": "2"
            },
            "created": "2020-5-8",
            "status": {
                "name": "DONE"
            }
        }
    }
]}

我想选择以下内容:

代码语言:javascript
运行
复制
[
    "abc",
    "Bug",
    "Major",
    "2020-5-11",
    "OPEN",
    "def",
    "Info",
    "Minor",
    "2020-5-8",
    "DONE"
]

csv应该是这样的:

代码语言:javascript
运行
复制
abc,Bug,Major,2020-5-11,OPEN
def,Info,Minor,2020-5-8,DONE

我试过$.issues.[*].[key,fields],我得到了

代码语言:javascript
运行
复制
  "abc",
  {
    "issuetype": {
      "name": "Bug",
      "id": "1",
      "subtask": false
    },
    "priority": {
      "name": "Major",
      "id": "3"
    },
    "created": "2020-5-11",
    "status": {
      "name": "OPEN"
    }
  },
  "def",
  {
    "issuetype": {
      "name": "Info",
      "id": "5",
      "subtask": false
    },
    "priority": {
      "name": "Minor",
      "id": "2"
    },
    "created": "2020-5-8",
    "status": {
      "name": "DONE"
    }
  }
]

但是,当我想选择例如只“创建”$.issues.[*].[key,fields.[created]

代码语言:javascript
运行
复制
[
  "2020-5-11",
  "2020-5-8"
]

这就是结果。

但我只是不知道如何在字段中选择"key“和"name”。如何使用jsonPath实现这一点,或者是否有更好的方法过滤jsonfile,然后将其转换为csv?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-12 21:52:06

我推荐一种更好的方法--创建一组表示JSON数据结构的Java类。当您将JSON读入这些类时,可以使用标准Java操作数据。

我还推荐了一个不同的JSON解析器--在本例中是Jackson,但还有其他解析器。为什么?主要是熟悉度--更多关于这方面的笔记,请稍后参阅。

从最终结果开始:假设我有一个名为Container的类,它包含JSON文件中列出的所有问题,然后我可以使用以下内容填充它:

代码语言:javascript
运行
复制
//import com.fasterxml.jackson.databind.ObjectMapper;

String jsonString = "{...}" // your JSON data as a string, for this demo.
ObjectMapper objectMapper = new ObjectMapper();
Container container = objectMapper.readValue(jsonString, Container.class);

现在,我可以以CSV格式打印所有问题,如下所示:

代码语言:javascript
运行
复制
container.getIssues().forEach((issue) -> {
    printCsvRow(issue);
});

在这里,printCsvRow()方法如下所示:

代码语言:javascript
运行
复制
private void printCsvRow(Issue issue) {
    String key = issue.getKey();
    Fields fields = issue.getFields();
    String type = fields.getIssuetype().getName();
    String priority = fields.getPriority().getName();
    String created = fields.getCreated();
    String status = fields.getStatus().getName();
    System.out.println(String.join(",", key, type, priority, created, status));
}

实际上,我会使用CSV库来确保正确格式化记录--以上只是为了说明如何访问JSON数据。

印刷内容如下:

代码语言:javascript
运行
复制
abc,Bug,Major,2020-5-11,OPEN
def,Info,Minor,2020-5-8,DONE

为了只过滤打开的记录,我可以这样做:

代码语言:javascript
运行
复制
container.getIssues()
        .stream()
        .filter(issue -> issue.getFields().getStatus().getName().equals("OPEN"))
        .forEach((issue) -> {
    printCsvRow(issue);
});

印刷内容如下:

代码语言:javascript
运行
复制
abc,Bug,Major,2020-5-11,OPEN

要启用Jackson,我将Maven与以下依赖项一起使用:

代码语言:javascript
运行
复制
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.10.3</version>
</dependency>

如果您不使用Maven,这就给了我3个JAR:jackson-databindjackson-annotationsjackson-core

为了创建我需要的嵌套Java类(以反映JSON的结构),我使用了一个工具,它使用示例JSON为我生成它们。

在我的例子中,我使用了这个工具,但是还有其他的。

我选择了“容器”作为根Java类的名称;JSON的源类型;并选择了Jackson 2.x注释。我还请求了getter和setter。

我将生成的类(字段、问题、问题类型、优先级、状态和容器)添加到我的项目中。

警告:这些Java类的完整性仅限于示例JSON。当然,您可以增强这些类,以更准确地反映您需要处理的实际JSON。

Jackson ObjectMapper负责将JSON加载到类结构中。

我选择使用杰克逊而不是JsonPath,只是因为熟悉。JsonPath似乎具有非常相似的对象映射功能--但我从未使用过JsonPath的这些特性。

最后注意:您可以在JsonPath中使用xpath样式谓词来访问单个数据项和项组--正如您在问题中所描述的那样。但是(根据我的经验),如果您想以更灵活的方式处理所有数据,那么创建Java类几乎总是值得的--特别是如果需要将JSON输入转换成不同的输出结构。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61753408

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档