我想把jsonobjcts转换成csv文件。到目前为止,Wy ( rows )尝试将json文件作为一个JSONObject (从googlecode.josn-简单库)加载,然后用jsonPath将它们转换成一个字符串数组,然后用于构建csv行。然而,我正面临着jsonPath的一个问题。从给定的例子来看.
{
"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"
}
}
}
]}我想选择以下内容:
[
"abc",
"Bug",
"Major",
"2020-5-11",
"OPEN",
"def",
"Info",
"Minor",
"2020-5-8",
"DONE"
]csv应该是这样的:
abc,Bug,Major,2020-5-11,OPEN
def,Info,Minor,2020-5-8,DONE我试过$.issues.[*].[key,fields],我得到了
"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]时
[
"2020-5-11",
"2020-5-8"
]这就是结果。
但我只是不知道如何在字段中选择"key“和"name”。如何使用jsonPath实现这一点,或者是否有更好的方法过滤jsonfile,然后将其转换为csv?
发布于 2020-05-12 21:52:06
我推荐一种更好的方法--创建一组表示JSON数据结构的Java类。当您将JSON读入这些类时,可以使用标准Java操作数据。
我还推荐了一个不同的JSON解析器--在本例中是Jackson,但还有其他解析器。为什么?主要是熟悉度--更多关于这方面的笔记,请稍后参阅。
从最终结果开始:假设我有一个名为Container的类,它包含JSON文件中列出的所有问题,然后我可以使用以下内容填充它:
//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格式打印所有问题,如下所示:
container.getIssues().forEach((issue) -> {
printCsvRow(issue);
});在这里,printCsvRow()方法如下所示:
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数据。
印刷内容如下:
abc,Bug,Major,2020-5-11,OPEN
def,Info,Minor,2020-5-8,DONE为了只过滤打开的记录,我可以这样做:
container.getIssues()
.stream()
.filter(issue -> issue.getFields().getStatus().getName().equals("OPEN"))
.forEach((issue) -> {
printCsvRow(issue);
});印刷内容如下:
abc,Bug,Major,2020-5-11,OPEN要启用Jackson,我将Maven与以下依赖项一起使用:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.3</version>
</dependency>如果您不使用Maven,这就给了我3个JAR:jackson-databind、jackson-annotations和jackson-core。
为了创建我需要的嵌套Java类(以反映JSON的结构),我使用了一个工具,它使用示例JSON为我生成它们。
在我的例子中,我使用了这个工具,但是还有其他的。
我选择了“容器”作为根Java类的名称;JSON的源类型;并选择了Jackson 2.x注释。我还请求了getter和setter。
我将生成的类(字段、问题、问题类型、优先级、状态和容器)添加到我的项目中。
警告:这些Java类的完整性仅限于示例JSON。当然,您可以增强这些类,以更准确地反映您需要处理的实际JSON。
Jackson ObjectMapper负责将JSON加载到类结构中。
我选择使用杰克逊而不是JsonPath,只是因为熟悉。JsonPath似乎具有非常相似的对象映射功能--但我从未使用过JsonPath的这些特性。
最后注意:您可以在JsonPath中使用xpath样式谓词来访问单个数据项和项组--正如您在问题中所描述的那样。但是(根据我的经验),如果您想以更灵活的方式处理所有数据,那么创建Java类几乎总是值得的--特别是如果需要将JSON输入转换成不同的输出结构。
https://stackoverflow.com/questions/61753408
复制相似问题