2012-01-14 39 views
2

我有一個XML(假設它是有效的),我必須解析它並將其存儲在樹中。在沒有附加庫的情況下解析標準C/C++中的XML

什麼是最好的方法來解析它,而不使用其他庫,只是基本的字符串操作?

請記住,我不必驗證它,只需解析並將其記憶到一棵樹。

+3

1)編寫你自己的解析器,只使用字符串的基本操作,2)解析。 – 2012-01-14 14:21:06

+8

**最好的方法是使用庫。到目前爲止最好! :-) – 2012-01-14 14:21:44

+1

規格在這裏:[xml規格](http://www.w3.org/XML/Core/#Publications)。要知道,全面處理XML的所有功能並不是一項簡單的任務。 – 2012-01-14 14:25:14

回答

7

XML的基本結構是非常簡單的:

<tagname [attribute[="value"] ...]>content</tagname> 

其中內容可同時含有普通文本和更多的XML結構或特殊形式

<tagname [attribute[="value"] ...]/> 

這相當於

<tagname [attribute[="value"] ...]></tagname> 

即,。空的內容。

所以,如果你不需要解釋DTD或者做其他花哨的東西,你可以做到以下幾點:

  1. 檢查的第一個非空白字符是<。如果沒有,你沒有XML,只能給出錯誤並退出。

  2. 現在跟在標記名稱之後,直到第一個空格或/>字符。保存。

  3. 如果下一個非空白字符是/,請檢查它後面是>。如果是這樣,你已經完成解析並可以返回你的結果。否則,您的XML格式不正確,可能會退出並顯示錯誤消息。

  4. 如果字符是>,那麼您已經找到了開始標記的結尾。現在遵循內容。繼續步驟6.

  5. 否則接下來是一個參數。解析並存儲結果,然後繼續步驟3.

  6. 閱讀內容,直到找到<字符。

  7. 如果該字符後跟/,則表示結束標記。檢查它是否跟着標籤名稱和>,如果是,則返回結果。否則,拋出一個錯誤。

  8. 如果你到了這裏,你已經找到了嵌套XML的開始。用這個算法解析,然後在6點繼續。

+1

我想你錯過了處理說明,評論和標記的部分... – 2012-01-14 14:50:09

+0

非常感謝!它幫助我瞭解解析XML的一般過程:) – Andrei 2012-01-14 14:56:59

+1

@KerrekSB:是的,我忘記了評論。處理指令和標記的部分屬於我在開頭提到的「其他奇特的東西」。但我省略的另一件事是名爲實體;但我相信這些可以通過後處理內容來處理。 – celtschk 2012-01-14 14:57:10

3

最好的和唯一的方法是從頭開始重新實現這樣的庫不使用任何其他庫...

歡迎你使用現有的庫,例如pugixml,例如。它的安裝就像將文件添加到項目並開始使用它一樣簡單。與其他驗證解析器(如Xerces)相比,它是輕量級的。

+0

@Downvoters:爲什麼downvote? – ybungalobill 2012-01-14 14:27:08

+0

Tnx的答案。使用現有的庫不是一種選擇。這只是一門課程的作業,我不必處理所有的XML功能,只是爲了輕鬆解析它。我的問題是解析它的最好方法是什麼?我在C++方面有一些經驗,但不是使用字符串。 – Andrei 2012-01-14 14:34:29

+0

@Andrei:那麼你不得不在OP中這樣寫。 – ybungalobill 2012-01-14 18:17:33

5

閱讀XML看起來很簡單,但正確地做它涉及到一些你並不真正想要處理的複雜性。事實上,編寫一個簡單的XML解析器有效地等同於創建另一個XML庫。我已經完成了,而這個不完整的版本正在我的磁盤上。即使你不需要驗證XML結構:

  • 您是否驗證或沒有,你需要處理像&lt;和實體引用一樣&#65;&#xa;
  • 平原的各種字符實體引用一個XML文檔的主體是相對簡單的,但標題是一個主要的難題,特別是DTD:有兩個版本略有不同,你可能需要處理內聯DTD
  • 即使身體不完全由於這些煩人的字符數據段而變得無足輕重
  • 即使沒有驗證您可能需要支持外部實體引用
  • 字符被接受和/或拒絕XML的各個部位也有些有趣
  • 注意,XML在統一的條款和該妥善處理規定並非完全微不足道:只使用charwchar_t就是不能削減它。

我實現的第一個版本是一個很好的小迭代器,用於彈出遇到的所有元素。這允許在選擇迭代器用戶時輕鬆停止和繼續解析的好功能。不幸的是,當我嘗試複製各種實體引用時,我沒有得到它。它可以很好地解析簡單的XML文件,但是規範中的一些怪癖我只是沒有得到正確的解釋。

對我來說最合適的是創建一個簡單的遞歸裁剪解析器和適當的緩衝區堆棧,以稍微透明地處理實體引用。然而,爲了完成這個工作,我仍然需要處理一些編碼問題,最後我只是有更高優先級的項目可以工作(在我的業餘時間,那是)。

綜上所述:很明顯,它可以像其他人一樣完成。這可能是一個毫無意義的練習,除非你有一個非常好的想法,這使得你的實現比其他選擇更適合。

+0

感謝您的回答!我認爲我正在尋找迭代器,我不想在遞歸,緩衝區等方面變得複雜一些。 – Andrei 2012-01-14 15:12:08

相關問題