簡體   English   中英

SnakeYAML低級API無法正確解析MapNode

[英]SnakeYAML low-level API not parsing MapNode correctly

我想對yml文件中的值進行一些處理。 有人建議我為此使用snakeYAML的低級API 因此,我已經使用該代碼編寫了一些代碼,但是由於以下原因,我幾乎陷入了困境。

這是我編寫的代碼:

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

Prakash: 
 Lucky:
  Number: 11

Really? :  NotAtAll

這是在控制台上打印的內容(在一行中,我對其進行了格式化並添加了注釋以使其可讀):

<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其也ScalarNode通過搜索valueNode=<org.yaml.snakeyaml.nodes.ScalarNode ,然后處理在該節點的值。

但是問題是我不知道為什么在組成地圖節點時會放置垃圾值。 所以這是我的問題:

  1. 如何正確編寫yaml文件,以便地圖節點正確顯示而不是垃圾值?
  2. 在完成處理並將值成功替換為處理后的值之后,如何將它們放回yaml文件?
  3. 如果您認為這是一種垃圾處理方法,請提出一個更好的建議。

您獲得“垃圾值”的原因是因為MappingValue的toString方法中的這一部分:

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節點(即Mapping和Sequences)中。

這意味着您的節點樹確實已經正確組成,並且您根本不應該使用toString進行檢查。 那回答了您的第一個問題。

要將其寫回YAML文件,請使用類似

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因為在處理事件流時丟失的信息少於在處理組合圖時丟失的信息(這意味着輸出將與輸入更相似)。

然后,您可以遍歷生成的事件,識別要更改的事件,並用更改后的事件替換它們,然后使用上面的代碼中所示的Emitter。

在這里用一些Python代碼展示如何從字符串列表(有點像“ YAML路徑”)中識別事件流中的事件,但是該代碼將事件插入給定路徑而不是更改它們。 Python和Java API有點相似,因此,如果您可以閱讀Python,那么該代碼可能會對您有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM