?? xmlparse.pas
字號:
//------------------------------------------
// 名稱:XMLParse
// 功能:XML解析類庫
// 引入:xmldom, XMLIntf, msxmldom, XMLDoc, Classes, IdCoder, IdCoder3to4, IdCoderMIME, IdBaseComponent
// 引出:無
// 版本:1.0
// 作者:羅庚
// 時間:2004-01-05
// 說明: 改類用于簡化XML的解析工作, 但其有個限定, 只能解析不帶域的XML.而且不能直接解析如下格式的片斷
// <XMLPackage>
// <data id="1">
// <row id="1" name="子藍" sex="男" age="24" duty="軟件工程師"/>
// <row id="2" name="天使藍" sex="女" age="25" duty="商務經理"/>
// </data>
// <data id="2">
// <row id="1" name="子藍" sex="男" age="24" duty="軟件工程師"/>
// <row id="2" name="天使藍" sex="女" age="25" duty="商務經理"/>
// </data>
// </XMLPackage>
// 這是應為存在兩個<data>元素的實例, intRowIndex 只能用于區分strNodePath指定的最尾部的同名節點(如row元素), 而不能區分出樹枝(如<data id="2">這個節點)
// 但也不是說沒有辦法解析, 可以用 GetNode<data id="2"> 把 data 節點讀出, 然后再再手工解析. 或者可以考慮讓 GetNode 支持數組格式 ,如可以讓 strNodePath='Package.data[1].row[0]'這樣的格式.
//------------------------------------------
unit XMLParse;
interface
uses XMLIntf, XMLDoc, Classes, IdCoderMIME ; // msxmldom,,xmldom,IdCoder, IdCoder3to4,IdBaseComponent
Type
TXMLDOMEx = Class(TObject)
private
XMLDocument :IXMLDocument;
strXMLFileName :String;
public
constructor Create( strFileName :String='' );
destructor destory();
function LoadXMLFile( strFileName :String ):Boolean;
function GetNodeAttribute( strNodePath, strAttribute: String; var strValue: String; intRowIndex: Integer=0; const dep: Char='.'):Boolean;
function GetNodeText( strNodePath :String; var strValue :String; intRowIndex :Integer=0 ; const dep: Char='.'):Boolean;
function GetNodeStream( strNodePath :StrIng; var stmValue :TStream; intRowIndex :Integer=0 ; const strEncode :String='Base64';const dep: Char='.'):Boolean;
function GetChridNodeCount( strParentNodePath, strChildNodeName: String; const dep: Char='.'): Integer;
function GetNode( strNodePath: String; intRowIndex: Integer=0; const dep: Char='.'): IXMLNode;
end;
implementation
{ TXMLDOMEx }
//---------------------------------------------------------------------------
// 名稱: Create
// 功能: 創建對象,建立IXMLDocument接口
// 輸入:strFileName :String='' XML文件名
// 輸出:無
// 版本:1.0
// 作者:羅庚
// 時間:2004-01-03
//---------------------------------------------------------------------------
constructor TXMLDOMEx.Create(strFileName: String);
begin
XMLDocument := TXMLDocument.Create( strFileName );
XMLDocument.Active := True;
strXMLFileName := strFileName;
end;
//---------------------------------------------------------------------------
// 名稱: GetChridNodeCount
// 功能: 獲取XML中節點strParentNodePath 的子節點 strChildNodeName 的個數
// 輸入:strParentNodePath 父節點名,默認使用.分割,如 XMLPackage.data.row;
// strChildNodeName 要確定其個數的子節點, 默認為空, 表示確定所有父節點下的子節點個數
// dep 路徑 strNodePath 分割符號, 默認為 . ,如 strNodePath='XMLPackage>data>row',則改屬性置為 >
// 輸出:Integer 找到的子節點個數
// 版本:1.0
// 作者:羅庚
// 時間:2004-01-03
//---------------------------------------------------------------------------
function TXMLDOMEx.GetChridNodeCount(strParentNodePath,
strChildNodeName: String; const dep: Char='.'): Integer;
var XMLParentNode: IXMLNode; //'XMLPackage.memo'
iCount, i :Integer;
begin
iCount := 0;
XMLParentNode := GetNode( strParentNodePath, 0, dep );
if not assigned( XMLParentNode ) then
begin
Result := -1; // 無效的父節點
exit;
end;
if strChildNodeName = '' then
Result := XMLParentNode.ChildNodes.Count
else
begin
for i := 0 to XMLParentNode.ChildNodes.Count -1 do
begin
if XMLParentNode.ChildNodes.Nodes[i].NodeName = strChildNodeName then
inc( iCount );
end;
Result := iCount;
end;
end;
//---------------------------------------------------------------------------
// 名稱: GetNode
// 功能: 獲取XML中編號第intRowIndex個路徑為strNodePath的節點.
// 注意: 本類庫的主要限制也就在這, 就是intRowIndex只能對strNodePath尾部的節點有控制作用
// 輸入:strNodePath 節點名,默認使用.分割,如 XMLPackage.data.row;
// intRowIndex 尾部節點的索引, 如在data節點中包含多個 row節點時, 這個參數說明獲取第幾個row節點(row[i]),默認為0
// dep 路徑 strNodePath 分割符號, 默認為 . ,如 strNodePath='XMLPackage>data>row',則改屬性置為 >
// 輸出:IXMLNode 找到的節點, 沒有找到返回nil
// 版本:1.0
// 作者:羅庚
// 時間:2004-01-03
//---------------------------------------------------------------------------
function TXMLDOMEx.GetNode(strNodePath: String; intRowIndex: Integer;
const dep: Char): IXMLNode;
var XMLNode: IXMLNode;
sltNodePath :TStrings;
iNodePathCount, iNodePathIndex :Integer;
bIsFoundChild :Boolean;
i:Integer;
strBeFoundNodeName :String;
begin
sltNodePath:=TStringList.Create;
sltNodePath.Delimiter:= dep;
sltNodePath.DelimitedText:= strNodePath;
// 獲取根節點
iNodePathCount := sltNodePath.Count;
iNodePathIndex := 0;
XMLNode := XMLDocument.DocumentElement;
// End .
bIsFoundChild := XMLNode.NodeName = sltNodePath.Strings[ iNodePathIndex ];
inc( iNodePathIndex );
while bIsFoundChild and ( iNodePathIndex < iNodePathCount ) do
begin
strBeFoundNodeName := sltNodePath.Strings[ iNodePathIndex ];
// 遍歷所有的子節點, 從中查找下名為 strBeFoundNodeName 的節點.
bIsFoundChild := False;
for i:= 0 to XMLNode.ChildNodes.Count - 1 do
begin
// 當尋找到當前節點的子節點是本次要尋找的節點時候, 選擇往下層尋找還是本層尋找第intRowIndex個同名的節點
if XMLNode.ChildNodes.Nodes[i].NodeName = strBeFoundNodeName then
begin
// 當還沒有到達strNodePath中指定的最后的節點時,繼續往下層遍歷
if iNodePathIndex <> (iNodePathCount - 1) then
begin
bIsFoundChild := True;
XMLNode := XMLNode.ChildNodes.Nodes[i];
break;
end
// End .
else
// 當已經尋找到strNodePath中指定的最后的節點的時候,控制往下尋找第 intRowIndex 個名為 strBeFoundNodeName 節點
begin
Dec( intRowIndex );
if intRowIndex < 0 then
begin
bIsFoundChild := True;
XMLNode := XMLNode.ChildNodes.Nodes[i];
break;
end;
end;
// End .
end;
// End .
end;
// End . 結束尋找子節點.
inc( iNodePathIndex );
end;
// end of while
if bIsFoundChild then
Result := XMLNode
else
Result := nil;
end;
//---------------------------------------------------------------------------
// 名稱: GetNodeAttribute
// 功能: 獲取XML中編號第intRowIndex個路徑為strNodePath的節點的屬性 strAttribute.
// 輸入:strNodePath 節點名,默認使用.分割,如 XMLPackage.data.row;
// strAttribute 要獲取的屬性名稱, 區分大小寫
// strValue 輸出的屬性值
// intRowIndex 尾部節點的索引, 如在data節點中包含多個 row節點時, 這個參數說明獲取第幾個row節點(row[i]),默認為0
// dep 路徑 strNodePath 分割符號, 默認為 . ,如 strNodePath='XMLPackage>data>row',則改屬性置為 >
// 輸出:boolean 成功返回true, false 表示無效的節點或者屬性
// 版本:1.0
// 作者:羅庚
// 時間:2004-01-03
//---------------------------------------------------------------------------
function TXMLDOMEx.GetNodeAttribute(strNodePath, strAttribute: String;
var strValue: String; intRowIndex: Integer=0; const dep: Char='.'): Boolean;
var XMLNode: IXMLNode;
begin
XMLNode := GetNode( strNodePath, intRowIndex, dep );
Result := True;
if ( not assigned( XMLNode )) or ( not XMLNode.HasAttribute( strAttribute )) then
begin
Result := False; // 無效的節點或者屬性
strValue := '';
end
else
begin
strValue := XMLNode.Attributes[ strAttribute ];
end;
end;
//---------------------------------------------------------------------------
// 名稱: GetNodeText
// 輸入:strNodePath 節點名,默認使用.分割,如 XMLPackage.data.row;
// strValue 改節點包含的Text
// intRowIndex 尾部節點的索引, 如在data節點中包含多個 row節點時, 這個參數說明獲取第幾個row節點(row[i]),默認為0
// dep 路徑 strNodePath 分割符號, 默認為 . ,如 strNodePath='XMLPackage>data>row',則改屬性置為 >
// 輸出:1. true 成功返回
// 2. false 無效的節點或者該節點不能包括單獨的Text
// 版本:1.0
// 作者:羅庚
// 時間:2004-01-03
//---------------------------------------------------------------------------
function TXMLDOMEx.GetNodeText(strNodePath :String; var strValue :String;
intRowIndex :Integer=0 ; const dep: Char='.'): Boolean;
var XMLNode: IXMLNode;
begin
XMLNode := GetNode( strNodePath, intRowIndex, dep );
Result := True;
if ( not assigned( XMLNode )) or (not XMLNode.IsTextElement ) then
begin
Result := False; // 無效的節點或者該節點不能包括單獨的Text
strValue := '';
end
else
begin
strValue := XMLNode.Text;
end;
end;
//---------------------------------------------------------------------------
// 名稱: GetNodeStream
// 輸入:strNodePath 節點名,默認使用.分割,如 XMLPackage.data.row;
// strStrem 輸出的DecodeBase64流
// intRowIndex 尾部節點的索引, 如在data節點中包含多個 row節點時, 這個參數說明獲取第幾個row節點(row[i]),默認為0
// strEncode Decode的代碼格式, 這個類庫只支持 Base64, 但可以擴充.
// dep 路徑 strNodePath 分割符號, 默認為 . ,如 strNodePath='XMLPackage>data>row',則改屬性置為 >
// 輸出:1. true 成功返回
// 2. false 無效的節點或者該節點不能包括單獨的Text
// 版本:1.0
// 作者:羅庚
// 時間:2004-01-03
//---------------------------------------------------------------------------
function TXMLDOMEx.GetNodeStream(strNodePath: StrIng;
var stmValue: TStream; intRowIndex: Integer;
const strEncode: String; const dep: Char): Boolean;
var strText :String;
DecodeBase64: TIdDecoderMIME;
begin
stmValue.Size := 0;
stmValue.Position := 0;
if not GetNodeText( strNodePath, strText, intRowIndex, dep ) then
begin
Result := False; // 無效的節點或者該節點不能包括單獨的Text
exit;
end;
DecodeBase64 := TIdDecoderMIME.Create(nil);
DecodeBase64.DecodeToStream( strText, stmValue );
DecodeBase64.Free;
end;
//---------------------------------------------------------------------------
// 名稱: LoadXMLFile
// 功能: 載入一個XML文件
// 輸入:strFileName XML的文件名
// 輸出:1. true 成功返回
// 2. false 讀取失敗或者解析失敗
// 版本:1.0
// 作者:羅庚
// 時間:2004-01-03
//---------------------------------------------------------------------------
function TXMLDOMEx.LoadXMLFile(strFileName: String): Boolean;
begin
XMLDocument.Active := False;
XMLDocument.LoadFromFile( strFileName );
XMLDocument.Active := True;
end;
//---------------------------------------------------------------------------
// 功能: 類銷毀時, 撤銷所有對象
// 輸入:無
// 輸出:無
// 版本:1.0
// 作者:羅庚
// 時間:2004-01-03
//---------------------------------------------------------------------------
destructor TXMLDOMEx.destory;
begin
if assigned( XMLDocument ) then
begin
// XMLDocument._Release; 這句語句倒不一定需要, 這里只是為了保險.
XMLDocument := nil;
end
end;
end.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -