2

我正在寻找一种处理 JSON 的方法,其中包括 JS 注释。我知道,评论对于 JSON 是不合法的,但不幸的是,我需要读取/写入带有评论的 JSON 文件。

我找到了一种使用杰克逊写评论的方法。本守则

JsonGenerator gen = factory.createGenerator(System.out);
gen.writeStartObject();
gen.writeStringField("a", "b");
gen.writeRaw("\n/*------------*/\n");
gen.writeStringField("c", "d");
gen.writeEndObject();
gen.close();

生成以下 JSON:

{"a":"b"
/*------------*/
,"c":"d"}

如果我开始解析这个 JSON

factory.enable(JsonParser.Feature.ALLOW_COMMENTS);
JsonParser parser = factory.createParser("{\"a\":\"b\"/*------------*/,\"c\":\"d\"}");
while (parser.nextToken() != JsonToken.END_OBJECT) {
    System.out.println(parser.currentToken() + ":" + parser.getText());
}

评论和所有格式都被跳过。甚至没有像“RAW”或“COMMENT”这样的 JsonToken。

有没有办法使用 Jackson(或其他 Java 库)解析带有嵌入式原始数据的 JSON?

4

2 回答 2

1

NodeJ 的方式

您可以通过节点包来实现这一点 - node-comment-json

基本上,这个库是专门设计来维护评论的,并且还允许美化 JSON 的输出。

这是我在安装软件包后可以做的npm i -g comment-json

$ node
> const { parse, stringify } = require('comment-json') 
> const parsed = parse(`{"a":"b"/*------------*/,"c":"d"}`)
> prased
{ a: 'b', c: 'd' }
> parsed['a'] = 'df'
> parsed
{ a: 'df', c: 'd' }
> stringify(parsed, null, 2)
'{\n  "a": "df" /*------------*/,\n  "c": "d"\n}'

现在,我知道这可以作为节点包使用。我们可以通过 node 使用它,或者如果确实需要通过 Java 使用它。

Java 解决方法

安装 NPM 和包:

使用frontend-maven-plugin,您可以安装 node/npm 以及包。所以你的 pom.xml 可能看起来像:

<plugin>
    ...
    <executions>
        <execution>
            <!-- optional: you dont really need execution ids -->
            <id>install node and npm</id>
            <goals>
                <goal>install-node-and-npm</goal>
            </goals>
            <!-- optional: default phase is "generate-resources" -->
            <phase>generate-resources</phase>

            <configuration>
                <nodeVersion>v6.9.1</nodeVersion>
            </configuration>
        </execution>
        <execution>
            <id>npm install</id>
            <goals>
               <goal>npm</goal>
            </goals>

            <!-- optional: default phase is "generate-resources" -->
            <phase>generate-resources</phase>

            <configuration>
            <!-- Install the comment-json-->
            <arguments>install -g comment-json</arguments>
            </configuration>
         </execution>
    </executions>
</plugin>

创建一个 NodeJs 脚本,它将解析参数并解析所需的逻辑

我编写了一个示例 app.js 脚本,其中除了以下参数:

  • JSON:"{\"a\":\"b\"/*------------*/,\"c\":\"d\"}"
  • 改变的关键:"a"
  • 要更改的新值:"df"

应用程序.js:

const {
  parse,
  stringify
} = require('comment-json');

 const parsed = parse(process.argv[2]);
 parsed[process.argv[3]] = process.argv[4];

 console.log(stringify(parsed, null, 2))

因此,如果我将其执行为: node app.js "{\"a\":\"b\"/*------------*/,\"c\":\"d\"}" "a" "df",它将在控制台上打印:

{
  "a": "df" /*------------*/,
  "c": "d"
}

使用ProcessBuilder、执行脚本并从 console.log 捕获输出

也使用IOUtils

List<String> commands = new LinkedList<String>();
commands.add("node");
commands.add("app.js"); // You need the actual /path/to/app.js
commands.add("{\"a\":\"b\"/*------------*/,\"c\":\"d\"}");
commands.add("a");
commands.add("df");

ProcessBuilder processBuilder = new ProcessBuilder(commands);
String output = IOUtils.toString(processBuilder.start().getInputStream(), StandardCharsets.UTF_8);
于 2021-04-19T05:43:21.170 回答
0

不知道为什么需要解析来自 json 的推荐。如果您想从 json 中查看推荐,为什么不直接将 json 作为字符串读取并解析出推荐。这是阅读推荐的正则表达式示例;

final Pattern pattern = Pattern.compile("/\\*.+\\*/", Pattern.DOTALL);
final Matcher matcher = pattern.matcher("{\"a\":\"b\"/*------------*/,\"c\":\"d\"}");
matcher.find();
System.out.println(matcher.group(0));
于 2021-04-18T02:37:34.137 回答