標籤:
這個程式可以用於解析任何合法的XML字串。
首先是看一下程式的運行效果:
以解析這樣一個XML的字串為例:
<?xml version="1.0" encoding="UTF-8"?><BookInfo><Owner><OwnerName>張三</OwnerName><OwnerAge>1234</OwnerAge></Owner><BookMes><BookName>時間簡史</BookName><ISDN>234343453534</ISDN><Writer>霍金</Writer></BookMes></BookInfo>
首先是開啟應用程式
然後將上面所示的字串複製到文本編輯框中,然後點擊解析按鈕,會出現下面的效果
如所示,可以 “XML中的欄位標籤:XML中對應標籤的值” 的格式顯示解析的效果。
然後看一下代碼
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, XMLIntf, XMLDoc;type TForm1 = class(TForm) edt1: TEdit; btn1: TButton; procedure btn1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}procedure ReadXml(Node: IXMLNode; var showmess: string);var NodeList: IXMLNodeList; strName: string; i: Integer;begin if not Node.HasChildNodes then Exit; nodeList := node.ChildNodes; for i := 0 to nodeList.Count - 1 do begin strName := nodeList[i].NodeName; if nodeList[i].IsTextElement then //如果是元素 begin showmess:= showmess + strName + ‘:‘ + NodeList[i].NodeValue + #13#10; end else if nodeList[i].HasChildNodes then //如果有子節點 begin ReadXml(NodeList[i], showmess); end; end;end;procedure TForm1.btn1Click(Sender: TObject);var sXML, showmess: string; ComInstrXML: IXMLDocument; mainNode: IXMLNode;begin showmess:= ‘‘; sXML:= edt1.Text; sXML:= StringReplace(sXML, ‘UTF-8‘, ‘gbk‘, [rfReplaceAll]); try ComInstrXML:= LoadXMLData(sXML); mainNode:= ComInstrXML.DocumentElement; readXML(mainNode, showmess); ShowMessage(showmess); except on E: Exception do begin ShowMessage(E.Message); end; end;end;end.
講解一下代碼
0.建議這樣使用XML解包
本例中的程式,在解包之後是將標籤以及對應的值顯示在彈出框上,這樣只是為了示範解析XML的效果。
建議在開發中將解析好的XML節點,以節點的標籤作為Key,以節點的內容作為value,插入到一個可以搜尋的鏈表或者其他什麼可以根據Key進行搜尋的容器類中,然後在之後使用的時候就可以很方便的搜尋到解析後的值。
1.遞迴解包XML
因為XML本身就是一個遞迴的結構,所以解包XML,也就是其中的ReadXML 方法使用的就是遞迴的方法,遞迴結束標誌是:正在解析的XML標籤是一個元素,沒有子節點。
2.字元編碼的問題
在 TForm1.btn1Click(Sender: TObject) 方法中,我們可以看到首先將XML字串中的 ‘UTF-8‘ 替換為 ‘gbk‘,因為如果編碼方式是UTF-8:<?xml version="1.0" encoding="UTF-8"?>,那麼如果XML中存在中文,那麼解析的時候會報錯(如果全部為英文,那麼就不會報錯),如
如果將UTF-8替換為gbk,,那麼在解析XML的時候就不會報這樣的錯誤。
另外如果以不包含編碼格式的XML字串,如:<BookInfo><Owner><OwnerName>張三</OwnerName><OwnerAge>1234</OwnerAge></Owner><BookMes><BookName>時間簡史</BookName><ISDN>234343453534</ISDN><Writer>霍金</Writer></BookMes></BookInfo>,沒有 <?xml version="1.0" encoding="UTF-8"?>的話,此時就算有 sXML:= StringReplace(sXML, ‘UTF-8‘, ‘gbk‘, [rfReplaceAll]); 這樣的替換字元編碼的代碼也是沒有用的,也沒有辦法改成gbk的編碼,所以仍然會報上面的異常。
所以請注意字元編碼的問題,尤其是既有中文又有英文的時候。
3.stringReplace函數的使用
function StringReplace (const S, OldPattern, NewPattern: string; Flags: TReplaceFlags): string;
rfReplaceAll:全部替換
rfIgnoreCase:忽略大小寫
例子
var aStr: String; begin aStr := ‘This is a book, not a pen!‘; ShowMessage(StringReplace (aStr, ‘a‘, ‘two‘, []));//This is two book, not a pen!只替換了第一個符合的字串 ShowMessage(StringReplace (aStr, ‘a‘, ‘two‘, [rfReplaceAll]));//This is two book, not two pen!替換了所有符合的字串 aStr := ‘This is a book, not A pen!‘; ShowMessage(StringReplace (aStr, ‘a‘, ‘two‘, [rfReplaceAll]));//This is two book, not A pen!只替換了符合的字串(小寫a) ShowMessage(StringReplace (aStr, ‘a‘, ‘two‘, [rfReplaceAll, rfIgnoreCase]));//This is two book, not two pen!不管大小寫替換了所有符合的字串end;
4.分行符號
注意代碼中有這樣一行代碼:
showmess:= showmess + strName + ‘:‘ + NodeList[i].NodeValue + #13#10;
其中的 #13#10 表示分行符號
Delphi之通過程式碼範例學習XML解析