2011-08-31 238 views
0

我有一組將C++類序列化爲XML的C++類。尼斯和丹迪。 我需要一個反序列化例程來初始化XML流中的相同類。C++中的XML序列化/反序列化

對於我來說不清楚的是,如何使用expat或tinyXML解析XML流,這些流解析器知道將XML用於實例供其使用,以便使用它自行初始化。

傳統上這是如何完成的?解析XML文件並創建適當的類非常容易,因爲XML正在被解析,但是反序列化成員函數,這是什麼樣的?

由於 禮

+1

我不知道「傳統」,但一個*工廠*想到。 –

回答

0

你的序列化格式必須包括指示對象的類的元件被序列化。例如,你可以開始連載的對象與每個XML:

<object> 
    <class>ClassName</class> 
    ... object data here 
</object> 

這意味着每一個你的C++類必須指定一個唯一的字符串名稱在XML編寫。

你使用哪個XML解析器並不重要。您的反序列化函數必須讀取類名並將其映射到實際的類。以最簡單的形式,這可以通過一系列if語句來完成,但是如果你願意的話,你當然可以提出更詳細的機制。一旦你知道這個類,你可以創建一個空實例並假設你的所有類都繼承自一個基類,然後調用一個在基類中是純虛擬的虛擬函數並在所有子類中實現。 fromXML()方法將解析XML樹的其餘部分,並根據從中讀取的數據初始化對象實例。

0

當您將類序列化爲XML時,每個節點都必須包含一些其運行時類型的標識符。對於反序列化,創建一個std::unordered_map,將這些類型標識符映射到每種類型的工廠函數。這將要求工廠函數具有相同的簽名,所以您需要從通用接口派生所有可序列化的類。在運行時降低工廠函數的返回值,具體取決於類型標識符。創建setter/getters來訪問每個屬性併爲特定的節點類型賦值。

如果您使用的是DOM解析器,事情可能會稍微簡單一些,因爲您在遇到它時可以獲得有關節點的所有信息。

使用SAX解析器,您必須創建子節點類併爲遇到的每個節點設置屬性值&。在閱讀XML文件時,您的XML解析器應允許可以重寫的回調或虛擬方法通知新屬性節點&。或者,如果你不介意花錢,最簡單的辦法就是讓其他人爲你做這項工作。如果你不介意花錢,最簡單的辦法就是讓其他人爲你做這項工作。我從來沒有使用過Code Synthesis XSD,但它的設計正是爲了你想要做的。