天天看點

Delphi中解析Xml的控件-SimDesign NativeXml

Delphi中解析Xml的控件-SimDesign NativeXml

正在學習,感覺應用很友善。無源代碼的版本還是免費的。

Delphi中解析Xml的控件-SimDesign NativeXml

SimDesign.NativeXml是一個delphi和bcb的XML控件,包含一個精巧的Delphi XML執行,使你能在程式中讀寫XML文檔。 

http://www.simdesign.nl/xml.html 

網上有一個利用SimDesign.NativeXml生成XML的例子。

一個更加強大易用的XML庫 -- NativeXML 

原來一直使用Delphi自帶的TXMLDocument類來進行XML檔案的讀寫,雖然麻煩了一點,但功能上來說還不錯。隻是有一個地方讓我實在不舒服 - 每次建立TXMLDocument類執行個體的時候必須傳入TComponent對象,這就意味着,如果我把對XML檔案的讀寫封裝到一個類裡面,那麼在建立這個自定義類的時候就必須也傳入TComponent對象。

我嘗試過很多方法,但是都無法避免,最後試着上網找了找,于是就找到了NativeXML這個庫。

下載下傳之後馬上打開Demo看了看,cool,建立TNativeXML的時候隻需要傳入xml檔案路徑就可以,再往下看就讓我開始驚喜了。它已經把大多數操作都封裝好了,而且還具有把任意對象序列化的能力。 

比如,你能把整個Form通過 TsdXmlObjectWriter = class(TPersistent) 類存入一個XML檔案,下次再讀取。這樣使得遠端傳輸對象變得很簡單了。

下面就是一個使用NativeXML庫的例子:

目标XML結構:

  <bookshift> 

      <book author = "test_author">

          <date>2000-01-01</date>

      </book>

  </bookshift> 

delphi 代碼: 

  procedure WriteTest;

  var 

    xml : TNativeXML;

    n_bs : TXMLNode; 

  begin 

    //

建立根節點

    xml := TNativeXml.CreateName('bookshift');

    xml.EncodingString := 'GB2312';

    //

輸出風格為易讀

    xml.XmlFormat := xfReadable;

    //

建立Book節點

    n_bs := xml.Root.NodeNew('book');

    //

寫入Book節點的屬性

    n_bs.WriteAttribuiteString('author','test_author');

    //

建立Book節點下屬date節點并寫入值

     n_bs.WriteString('date','2000-01-01');

     xml.SaveToFile('test.xml');

  end; 

打開test.xml檔案看看吧,和上面的格式一摸一樣。很簡單吧,我用這個庫重寫了原來的XML通路類,大約節省了40%的代碼量。SimDesign.NativeXml自帶的讀取XML文檔的例子。

 注意:以下代碼轉貼時有誤,未經測試

{ Example 3 

  Demo unit that shows how to import XML data into record structure.

  It is a "real-life" example written for one of our customers. 

  It shows how to use the method "NodesByName", creating a temporary

  list of node elements with the same name.

  It uses NativeXml to handle the conversion.

  This was the original request for the conversion:

  " Data should be placed in a record with this structure:

  type  

    FieldRecord= record

      FieldId: String;

      FieldReq: String;

      FieldType: String;

      FieldCap: String; 

      DependField: String;

      MetaType: String;

      MetaData: String;

    End;

  De enums and the hashtables must be stored in MetaData, 

  in the following manner: 

  Enums: enumvalue

_id1 + ',' + enum_caption1 + ";" +  enumvalue

_id2 + ',' + enum_caption2 + ";" + etc.....

  HashTable: codeid1 + ',' + hashdata1 + ';'  + 

    codeid2 + ',' + hashdata2 + etc...... 

  If there's no MetaData the field should remain empty. "

  Author: Nils Haeck, Simdesign

http://www.simdesign.nl 

  More info at:

http://www.simdesign.nl/xml.html 

unit Example3Main;

interface 

uses 

  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

  StdCtrls, NativeXml, ComCtrls;

type 

  // This is the record structure

  FieldRecord= record

    FieldId: String;

    FieldReq: String;

    FieldType: String;

    FieldCap: String;

    DependField: String;

    MetaType: String;

    MetaData: String;

  end; 

//

  TForm1 = class(TForm)

    mmXML: TMemo; 

    btnImportXML: TButton;

    lbStatus: TLabel;

    Label1: TLabel;

    lvTable: TListView;

    Label2: TLabel; 

    Label3: TLabel; 

    procedure btnImportXMLClick(Sender: TObject); 

    procedure lvTableData(Sender: TObject; Item: TListItem);

  private

  public 

    Fields: array of FieldRecord; // This is a dynamic array of records 

    procedure LoadFieldFromNode(var AField: FieldRecord; ANode: TXmlNode);

  end; 

var 

  Form1: TForm1;

implementation

{$R *.DFM} 

procedure TForm1.btnImportXMLClick(Sender: TObject);

// Read XML from TMemo and convert into record structure

var 

  i: integer; 

  ADoc: TNativeXml;

  ANode: TXmlNode;

  AList: TList; 

begin 

  ADoc := TNativeXml.Create;

  try 

    // Read from memo 

    ADoc.ReadFromString(mmXML.Text);  

    // A temporary list to hold references to the record elements

    AList := TList.Create;

    try 

      ANode := ADoc.Root.NodeByName('fields');

      if not assigned(ANode) then exit;

      // List of nodes that are named "field"

      ANode.NodesByName('field', AList);

      // Set dynamic array length

      SetLength(Fields, AList.Count); 

      // Import each element 

      for i := 0 to AList.Count - 1 do 

        LoadFieldFromNode(Fields[I], AList[I]);

      // Show table 

      lvTable.Items.Count := AList.Count;

      lvTable.Invalidate; 

      // Status 

      lbStatus.Caption := Format('Imported %d records', [AList.Count]);

    finally

      AList.Free;

    end;

  finally 

    ADoc.Free;

  end;

end; 

procedure TForm1.LoadFieldFromNode(var AField: FieldRecord;

  ANode: TXmlNode); 

// Load one field from the XML element ANode

var 

  i: integer; 

  AMeta: TXmlNode; 

  AEnum: TXmlNode;

  AList: TList;

begin 

  with AField, ANode do begin

    // Initialize record 

    FillChar(AField, SizeOf(AField), 0); 

    // The flat data 

    FieldId      := AttributeByName['id']; 

    FieldReq     := AttributeByName['required'];

    FieldType    := AttributeByName['type']; 

    FieldCap     := ReadString('caption'); 

    DependField  := AttributeByName['dependsfield'];

    // Meta data 

    AMeta := NodeByName('metadata');

    if assigned(AMeta) then

      with AMeta do 

      begin 

        MetaType := AttributeByName['type']; 

///

        // List that holds enumeration

        AList := TList.Create;

        try 

          // "enum" metadata 

          if MetaType = 'enum' then

          begin 

            AEnum := NodeByName('enumeration');

            if assigned(AEnum) then 

              AEnum.NodesByName('enumvalue', AList);

            // all enumeration values

            for i := 0 to AList.Count - 1 do

              with TXmlNode(AList[I) do 

                MetaData := MetaData + 

                  AttributeByName['id'] + ',' + ReadString('caption') + ';';

          end; 

          // "hashtable" metadata 

          if MetaType = 'hashtable' then  

          begin 

            AEnum := NodeByName('hashtable');

            if assigned(AEnum) then 

              AEnum.NodesByName('code', AList);

            // all enumeration values 

            for i := 0 to AList.Count - 1 do with TXmlNode(AList[I]) do

              MetaData := MetaData + 

                AttributeByName['id'] + ',' + valueAsString + ';';

          end;

        finally

          AList.Free;

        end;

      end;

  end;

end; 

procedure TForm1.lvTableData(Sender: TObject; Item: TListItem); 

// Add data to each item in the listview. We use the listview with OwnerData

begin 

  if (Item.Index >= 0) and (Item.Index < Length(Fields)) then

  begin 

    with Fields[Item.Index] do

    begin 

      Item.Caption := FieldID; 

      Item.SubItems.Add(FieldReq);

      Item.SubItems.Add(FieldType); 

      Item.SubItems.Add(FieldCap);

      Item.SubItems.Add(DependField);

      Item.SubItems.Add(MetaType);

      Item.SubItems.Add(MetaData);

    end;

  end;

end;

end.