首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SnakeYAML低级API不能正确解析MapNode

SnakeYAML低级API不能正确解析MapNode
EN

Stack Overflow用户
提问于 2019-08-03 15:45:33
回答 1查看 584关注 0票数 1

我想对yml文件中的值进行一些处理。有人建议我为此使用snakeYAML的低级API。所以,我用它编写了一些代码,但由于以下原因,我几乎被困住了。

下面是我写的代码:

代码语言:javascript
复制
public static void main(String[] args) throws Exception{
        Yaml yaml = new Yaml();
        FileReader contentFromFile=new FileReader("/Users/prakash.tiwari/Desktop/yamlInput.yml"); 
        for (Node node : yaml.composeAll(contentFromFile)) {
            System.out.println(node);
        }
    }

这是我的yamlInput.yml

代码语言:javascript
复制
Prakash: 
 Lucky:
  Number: 11

Really? :  NotAtAll

下面是控制台上打印的内容(在一行中,我对其进行了格式化,并添加了一条注释以使其可读性):

代码语言:javascript
复制
<org.yaml.snakeyaml.nodes.MappingNode 
(
    tag=tag:yaml.org,2002:map, 
    values=
    { 
        key=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=Prakash)>; 
        value=355629945     // Why is this a garbage value?
    }
    { 
        key=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=Really?)>; 
        value=
        <NodeTuple 
            keyNode=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=Really?)>; 
            valueNode=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=NotAtAll)>
        > 
    }
)>

此时,我可以通过搜索valueNode来提取也是ScalarNodevalueNode=<org.yaml.snakeyaml.nodes.ScalarNode,然后处理该节点中的值。

但问题是,我不知道为什么它在组合映射节点时放置垃圾值。以下是我的问题:

  1. 如何正确组合yaml文件,使映射节点正确显示而不是垃圾值?
  2. 在完成处理并成功地将值替换为已处理的值之后,如何将这些值放回yaml文件中?
  3. 如果你认为这是一个垃圾方法开始,请建议我一个更好的方法。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-04 11:30:12

获得“垃圾值”的原因是由于toString法中的这一节。

代码语言:javascript
复制
if (node.getValueNode() instanceof CollectionNode) {
    // to avoid overflow in case of recursive structures
    buf.append(System.identityHashCode(node.getValueNode()));
} else {
    buf.append(node.toString());
}

由于组合图可能包含循环(因为锚和别名在解析的现阶段已被解析),toString将不会递归到Collection节点(即映射和序列)。

这意味着您的节点树确实已经正确地组成了,您不应该使用toString来检查它。回答了你的第一个问题。

若要将其写回YAML文件,请使用以下内容

代码语言:javascript
复制
Emitter emitter = new Emitter(/* e.g. a FileWriter */ writer, new DumperOptions());
for (Event event : yaml.serialize(/* the root node */ node)) {
    emitter.emit(event);
}

要回答问题3:在前面的问题中,您提到要更改(加密)某些值,而不对其他值进行更改。如果是这样的话,我建议您使用yaml.parse而不是yaml.compose,因为在处理事件流时丢失的信息比处理组合图时丢失的信息要少(这意味着输出将更类似于输入)。

然后,您可以遍历生成的事件,识别要更改的事件并将其替换为已更改的事件,然后使用发射器,就像我在上面的代码中显示的那样。

我用一些这里代码演示了如何从字符串列表(种类-“YAML-路径”)中识别事件流中的事件,但是代码在给定路径上插入事件而不是修改它们。Python和Java有些相似,所以如果您可以阅读Python,那么这段代码可能会帮助您。

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

https://stackoverflow.com/questions/57339814

复制
相关文章

相似问题

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