delphi read xml element

2020-07-22 04:06发布

I'm new to XML and we need to do GeoCoding with the new Bing Spatial Data API. I've managed to get a result back from them in xml format. How would I read specific elements in the response, ie. the Link, Status and ErrorMessages?

<?xml version="1.0" encoding="utf-8"?>
<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/search/local/ws/rest/v1">
    <Copyright>Copyright © 2011 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.</Copyright>
    <BrandLogoUri>http://spatial.virtualearth.net/Branding/logo_powered_by.png</BrandLogoUri>
    <StatusCode>201</StatusCode>
    <StatusDescription>Created</StatusDescription>
    <AuthenticationResultCode>ValidCredentials</AuthenticationResultCode>
    <TraceId>ID|02.00.82.2300|</TraceId>
    <ResourceSets>
        <ResourceSet>
            <EstimatedTotal>1</EstimatedTotal>
            <Resources>
                <DataflowJob>
                    <Id>ID</Id>
                    <Link role="self">https://spatial.virtualearth.net/REST/v1/dataflows/Geocode/ID</Link>
                    <Status>Pending</Status>
                    <CreatedDate>2011-03-30T08:03:09.3551157-07:00</CreatedDate>
                    <CompletedDate xsi:nil="true" />
                    <TotalEntityCount>0</TotalEntityCount>
                    <ProcessedEntityCount>0</ProcessedEntityCount>
                    <FailedEntityCount>0</FailedEntityCount>
                </DataflowJob>
            </Resources>
        </ResourceSet>
    </ResourceSets>
</Response>

I'm using Delphi XE.

Regards, Pieter

4条回答
Root(大扎)
2楼-- · 2020-07-22 04:52

Since there is an XML Schema for these Bing Spatial Data Services, the easiest way to go is to import that schema using the Delphi XML Data Binding Wizard, then use the generated Delphi classes and interfaces to get your data from the XML, or put data in the XML.

This is similar to what Jørn E. Angeltveit suggested, but his suggestion uses the plain XML to generate the classes from.
That is OK if you don't have a schema, but when you have a schema, it is always better to import the schema.

Thare are many examples on using the Delphi XML Data Binding Wizard, so start there first.

If you need help on the binding: please ask a new specific question here.

查看更多
女痞
3楼-- · 2020-07-22 04:53

Now you should parse XML file. In the most simple case (you know XML tags) it could look like this:

var
  XMLDoc: IXMLDocument;
  Node: IXMLNode;
  I: Integer;
  role, link: string;

begin
  XMLDoc:= TXMLDocument.Create(nil);
  XMLDoc.LoadFromFile(AFileName);

  for I:= 0 to XMLDoc.DocumentElement.ChildNodes.Count - 1 do begin
    Node:= XMLDoc.DocumentElement.ChildNodes[I];
    if Node.NodeType = ntElement then begin
      if Node.NodeName = 'Link' then begin
        if Node.HasAttribute('role') then
          role:= Node.Attributes['role'];
        if not VarIsNull(Node.NodeValue) then
          link:= Node.NodeValue;
[..]
      end;
    end;
  end;
end;
查看更多
霸刀☆藐视天下
4楼-- · 2020-07-22 05:01

How about using some simple XPATH to get the requested values?

//Link[1]/node() - selects the first "Link" node from the whole document, and then selects the first child node of any kind. It just happens that the first child node is the unnamed node containing the actual https link.

Assuming the XML document is loaded into Doc: TXMLDocument, you can extract the Link with this code:

(Doc.DOMDocument as IDomNodeSelect).selectNode('//Link[1]/node()').nodeValue

You can find some documentation about XPath reading those XPath Examples on MSDN. You might find better documentation at w3schools. And to top it all up, here's a simple (but complete) console application that uses XPath to extract and display the 3 requested values:

program Project14;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Xmldoc,
  xmldom,
  ActiveX;

var X: TXMLDocument;
    Node: IDOMNode;
    Sel: IDomNodeSelect;

begin
  try
    CoInitialize(nil);

    X := TXMLDocument.Create(nil);
    try

      // Load XML from a string constant so I can include the exact XML sample from this
      // question into the code. Note the "SomeNode" node, it's required to make that XML
      // valid.

      X.LoadFromXML(
        '<SomeNode>'+
        '  <Link role="self">' +
        '    https://spatial.virtualearth.net/REST/v1/dataflows/Geocode/jobid' +
        '  </Link>' +
        '  <Status>Aborted</Status>' +
        '  <ErrorMessage>The data uploaded in this request was not valid.</ErrorMessage>' +
        '</SomeNode>'
      );

      // Shortcut: Keep a reference to the IDomNodeSelect interface

      Sel := X.DOMDocument as IDomNodeSelect;

      // Extract and WriteLn() the values. Painfully simple!

      WriteLn(Sel.selectNode('//Link[1]/node()').nodeValue);
      WriteLn(Sel.selectNode('//Status[1]/node()').nodeValue);
      WriteLn(Sel.selectNode('//ErrorMessage[1]/node()').nodeValue);

      ReadLn;
    finally X.Free;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
查看更多
家丑人穷心不美
5楼-- · 2020-07-22 05:08

If the XML-structure is fairly stable, you could use the XML binding tool to generate ordinary Delphi classes to access the xml-document.

Take a look at this page.

查看更多
登录 后发表回答