Parsing xml file Delphi

我的梦境 提交于 2020-01-01 07:03:19

问题


Firstly, I'm new to coding and Delphi, been on and off with it for a few months.

Below is a sample xml file.

What I'm trying to achieve is to Parse all data in each 'Name' section of the .xml file.

I have never done this before. Some guidance would be appreciated. I have looked at other questions on here similar to this but I cant quite get to grips with it.

I have no code example to provide....this is how stuck I am, I do not know where to begin.

<ds>
<Customers>
<Name>
<address_name>test 1</address_name> 
<address_line_1>test 1</address_line_1> 
<address_line_2>test 1</address_line_2> 
<address_line_3>test 1</address_line_3>
<postcode>test 1</postcode> 
<tel_no>test 1</tel_no> 
<fax_no>test 1</fax_no> 
<email_address>test 1<email_address/> 
<website>test 1<website /> 
</Name>
<Name>
<address_name>test 2</address_name> 
<address_line_1>test 2</address_line_1> 
<address_line_2>test 2</address_line_2> 
<address_line_3>test 2</address_line_3>
<postcode>test 2</postcode> 
<tel_no>test 2</tel_no> 
<fax_no>test 2</fax_no> 
<email_address>test 2<email_address/> 
<website>test 2<website /> 
</Name>
<Name>
<address_name>test 3</address_name> 
<address_line_1>test 3</address_line_1> 
<address_line_2>test 3</address_line_2> 
<address_line_3>test 3</address_line_3>
<postcode>test 3</postcode> 
<tel_no>test 3</tel_no> 
<fax_no>test 3</fax_no> 
<email_address>test 3<email_address/> 
<website>test 3<website /> 
</Name>
<Customers>
</ds>

Thanks,


回答1:


Depending on your Delphi SKU, you can do this using Delphi components very easily if it comes with the XMLMapper utility (in Delphi's Bin directory).

Create a new project containing

  • a TClientDataSet
  • a TDatasource
  • a TDbGrid

Connect the datasource to the CDS and the grid to the datasource;

  • add an XMLTransformerProvider

Set the ProviderName of the CDS to the name of the XMLTransformerProvider

In the FormCreate event, open the CDS.

Save the project.

Then, after correcting your XML file as I mentioned in my comment, load it into Delphi's XMLMapper.

In XML Mapper,

  • Select the DocumentView tab of the LH, Document pane

  • Double-click each of the nodes address_name .. website in turn

  • Click Create | DataPacket from XML in the menu

  • Click the Create and Test Transformation button on the Mapping tab of the central, Transformation pane.

  • From the menu, go to File | Save | Transformation and save your .Xtr file.

Back in your Delphi project, point the XMLDataFile property of the XMLTransformProvider at your XML file, & the TransformationFile of its TransformRead zub-component at your .Xtr file.

Compile & run your project.

The TFields created in your CDS have types and sizes determined by the .Xtr file generated by XMLMapper. You can fine-tune these as follows:

In XMLMapper:

  • Select the Node Properties tab of the Transformation pane.

  • In the Document View tab of the Document pane, click one of the data nodes-

  • You can then set its Data Type and Max Length on the Node Propertyies tab.




回答2:


A better aproach for your xml file would be:

<ds>
    <Customers>
        <Customer>
            <address_name>test 1</address_name> 
            <address_line_1>test 1</address_line_1> 
            <address_line_2>test 1</address_line_2> 
            <address_line_3>test 1</address_line_3>
            <postcode>test 1</postcode> 
            <tel_no>test 1</tel_no> 
            <fax_no>test 1</fax_no> 
            <email_address>test 1</email_address> 
            <website>test 1</website> 
        </Customer>
        <Customer>
            <address_name>test 2</address_name> 
            <address_line_1>test 2</address_line_1> 
            <address_line_2>test 2</address_line_2> 
            <address_line_3>test 2</address_line_3>
            <postcode>test 2</postcode> 
            <tel_no>test 2</tel_no> 
            <fax_no>test 2</fax_no> 
            <email_address>test 2</email_address> 
            <website>test 2</website> 
        </Customer>
        <Customer>
            <address_name>test 3</address_name> 
            <address_line_1>test 3</address_line_1> 
            <address_line_2>test 3</address_line_2> 
            <address_line_3>test 3</address_line_3>
            <postcode>test 3</postcode> 
            <tel_no>test 3</tel_no> 
            <fax_no>test 3</fax_no> 
            <email_address>test 3</email_address> 
            <website>test 3</website> 
        </Customer>
    </Customers>
</ds>

To read this file:

Insert this two uses: XMLDoc, XMLIntf;

Here is a procedure to read your XML file.

procedure TForm1.btnReadXmlFileClick(Sender: TObject);
var
  XmlFile : TXMLDocument;
  MainNode, CustomerNode : IXMLNode;
  i : Integer;
  XMLPath : string;
begin
  XMLPath := 'Z:\Temp\xmlToRead.xml'; //example of path
  XmlFile :=  TXMLDocument.Create(Application);
  try
    XmlFile.LoadFromFile(XMLPath);
    XmlFile.Active := True;
    MainNode := XmlFile.DocumentElement;

    for i:=0 to MainNode.ChildNodes['Customers'].ChildNodes.Count-1 do
    begin
      CustomerNode := MainNode.ChildNodes['Customers'].ChildNodes[i];
      //Here you can get any imformation
      ShowMessage(CustomerNode.ChildNodes['address_name'].Text);
      ShowMessage(CustomerNode.ChildNodes['address_line_1'].Text);
    end;
  finally
    FreeAndNil(XmlFile);
  end;
end;



回答3:


If the XML is structured similar to a single, flat dataset, you can create Dephi wrapper including reader and writer classes with XML Schema Binding Wizard (included in Delphi Professional).

The basic steps are

  • create a XSD file which represents the XML structure
  • run the XML Schema Binding Wizard

The first step can be done manually, maybe there are also tools which generate a XSD for you based on a sample XML. But for your XML it seems rather easy to write the XSD yourself.

Delphi generates a easy to use set of classes which can be used to read, modify, and write the XML document.




回答4:


Your XML is invalid (as well as having a terrible structure), but here's an example of some (valid) XML with a similar schema that might help you, using a straight IXMLDocument approach to populate a memo with a list of persons.

uses
  XMLIntf, XMLDoc;

const
  TestXML = '<?xml version="1.0"?>' +
            '<customers>' +
            '<people>' +
            '<person>' +
            '<name>John Smith</name>' +
            '<address>123 Main Street</address>'+
            '<city>Sometown</city>' +
            '<state>NY</state>' +
            '<zip>12345</zip>' +
            '</person>' +
            '<person>' +
            '<name>Jane Doe</name>' +
            '<address>456 Scenic View Blvd</address>'+
            '<city>Richtown</city>' +
            '<state>CT</state>' +
            '<zip>23456</zip>' +
            '</person>' +
            '</people>' +
            '</customers>';


procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Clear;
  ParseXMLToMemo;
end;

procedure TForm1.ParseXMLToMemo;
var
  Doc: IXMLDocument;
  Root: IXMLNode;
  PersonList: IXMLNodeList;
  Person: IXMLNode;
  i: Integer;
begin
  Doc := LoadXMLData(TestXML);
  Doc.Active := True;
  Root := Doc.DocumentElement;  // Get <people>
  PersonList := Root.ChildNodes['people'].ChildNodes;
  Person := PersonList.First;
  while Assigned(Person) do
  begin
    Memo1.Lines.Add(Person.ChildValues['name']);
    Memo1.Lines.Add(Person.ChildValues['address']);
    Memo1.Lines.Add(Person.ChildValues['city']);
    Memo1.Lines.Add(Person.ChildValues['state']);
    Memo1.Lines.Add(Person.ChildValues['zip']);
    Person := Person.NextSibling;
  end;
end;


来源:https://stackoverflow.com/questions/31455000/parsing-xml-file-delphi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!