2011-09-02 59 views
1

這個問題主要針對yaml-cpp(Jesse Beder)的作者,他曾請求過關於yaml-cpp使用的問題。如何使用yaml-cpp發出複雜的數據結構?

在許多地方,包括YAML-CPP文件, http://code.google.com/p/yaml-cpp/wiki/HowToEmitYAML#Using_Existing_Nodes

你剛纔提到的yaml-CPP不提供一種方式來修改現有內存YAML :: Node對象,您的建議在內存中修改YAML是:

  1. 用我自己的數據結構的YAML存儲在內存中,然後以某種方式序列化時反饋給YAML的CPP(基本上可以歸結爲重新實現在YAML多態性:: Node,與重新實現yaml-cpp的很多不同),o r

  2. 「目前最好的方法是使用發射器並從節點的子節點進行選擇和選擇」,即文檔中給出的示例。這種方法的問題在於它只適用於最簡單的情況。假設我想將一個元素添加到地圖序列中,其中地圖的其中一個元素本身就是一個列表?這可以很快得到任意複雜!找到插入新數據的位置,放出操縱器,這一切都必須「手動」完成。

使問題更加複雜,發射器是一個格式化和其唯一的輸出是一個字符串,所以我唯一的選擇是我的修改發射整個YAML文檔,然後再重新解析到一個新的內存表示。如果我正在對文檔進行很多更改,則此操作的效率足跡會快速增加。

我知道修改現有的Node有實際的挑戰(你如何處理對Node數據或子節點數據的現有引用?)。然而,在我看來,允許即時創建新的獨立節點並將其插入到內存樹中應該至少是直截了當的。例如,這是如何實現JsonCpp: http://jsoncpp.sourceforge.net

這將至少啓用您發現的「發射器」方法,如果效率低下,它可能是可行的解決方法。

我希望你對這些問題的看法。不幸的是,這些限制是相當嚴重的,並且考慮到yaml-cpp是唯一的C++/OO YAML庫,我想知道除了切換到JSON之外是否還有其他實用的選擇。

非常感謝您提前對您的想法!

回答

1

但是,在我看來,允許即時創建新的獨立節點並將其插入到內存樹中應該至少是直截了當的。

我想做到這一點(我已經看了JsonCpp這裏),但有三個問題:

  1. 有YAML和JSON之間的差異:YAML空區分節點和不存在的節點。

  2. yaml-cpp的當前行爲是在請求不存在的節點時拋出異常。

  3. 在YAML中,映射可以有任意鍵。

對於問題#2,這意味着它很可能我們將不得不(majorly!)打破目前的行爲,這讓我毫不猶豫地扣動扳機。

例如,在JsonCpp,當你寫

root["encoding"]; 

它會爲你創建一個默認的節點,如果它不存在。在yaml-cpp中,如果它不存在,會引發異常。人們可能會依賴於如下所示的代碼:

try { 
    root["encoding"]; // etc 
catch(const YAML::Exception&) { 
    // does not exist 
} 

最後,問題#3,你會如何指定密鑰,這是一個映射?如果有人寫

root[1] = 5; 

將在該實例root作爲序列與空第一要素,或者用一個鍵/值對{1, 5}的映射?如果是後者(這似乎更自然),然後

root[0] = 3; 
root[1] = 5; 

root[1] = 5; 
root[0] = 3; 

會有不同的行爲,這將是違反直覺。

基本上,底線是我已經考慮過這個問題,但我還沒有能夠爲它提供足夠好的API。我很樂意這樣做,所以如果你有任何想法,請讓我知道。

這就是說,我不確定是否stackoverflow是這樣的討論的最佳位置(我在yaml-cpp網站上寫過這篇文章,因爲很多人都在wiki上發佈瞭如何解答問題) - 所以感覺免費向我發送電子郵件(位於我的用戶頁面上)。

+0

非常感謝您提供快速,周到的答覆,傑西。對此,我真的非常感激。我確實會通過電子郵件向你發送跟進信息。 – DSII