delphi читает xml-элемент

Я новичок в XML, и нам нужно выполнять геокодирование с помощью нового API пространственных данных Bing. Мне удалось получить от них результат в формате xml. Как бы я прочитал определенные элементы в ответе, т. Е. Сообщение, Статус и Сообщения об ошибках?

<?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>

Я использую Delphi XE.

С уважением, Питер


person Pieter van Wyk    schedule 30.03.2011    source источник
comment
Добавьте тег, посвященный API пространственных данных Bing.   -  person Clóvis Valadares Junior    schedule 30.03.2011


Ответы (4)


Как насчет использования простого XPATH для получения запрошенных значений?

//Link[1]/node() - выбирает первый узел "Ссылка" из всего документа, а затем выбирает первый дочерний узел любого типа. Просто так случилось, что первый дочерний узел - это безымянный узел, содержащий фактическую ссылку https.

Предполагая, что XML-документ загружен в Doc: TXMLDocument, вы можете извлечь ссылку с помощью этого кода:

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

Вы можете найти некоторую документацию по XPath в этих примерах XPath в MSDN. Лучшую документацию можно найти в w3schools. И в довершение ко всему, вот простое (но законченное) консольное приложение, которое использует XPath для извлечения и отображения трех запрошенных значений:

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.
person Cosmin Prund    schedule 30.03.2011
comment
Теперь мне не нужно беспокоиться о рекурсивном поиске элементов в XML-файле. Я могу использовать запрос, чтобы получить то, что хочу! Спасибо. - person Pieter van Wyk; 31.03.2011
comment
При использовании XPath нужно быть предельно осторожным при установке Microsoft DOM. Старые версии лишь частично поддерживают языки XPath и используют другое смещение для первого элемента в массиве. И когда вы используете общий GUID для получения базовых объектов DOM (что делает большая часть кода), вы не знаете, какую версию DOM вы получаете. Меня это укусило несколько клиентов, которые обещали получить полностью обновленную систему тестирования, которая представляла собой обычную ванильную коробку с Windows 2003 без обновлений. - person Jeroen Wiert Pluimers; 01.04.2011

Если XML-структура достаточно стабильна, вы можете использовать инструмент привязки XML для генерации обычных классов Delphi для доступа к xml-документу.

Взгляните на эту страницу.

person Jørn E. Angeltveit    schedule 30.03.2011

Поскольку существует XML-схема для этих служб пространственных данных Bing, Самый простой способ - импортировать эту схему с помощью мастера привязки данных XML Delphi, а затем использовать сгенерированные классы и интерфейсы Delphi для получения данных из XML или помещения данных в XML.

Это похоже на то, что предлагал Йорн Э. Ангельтвейт, но его предложение использует простой XML для генерации классов.
Это нормально, если у вас нет схемы , но когда у вас есть схема, всегда лучше импортировать схему.

Есть много примеров использования мастера привязки данных XML Delphi, так что начните сначала с этого.

Если вам нужна помощь по привязке: задайте здесь новый конкретный вопрос.

person Jeroen Wiert Pluimers    schedule 30.03.2011
comment
Для OP стоит попробовать мастера привязки, если он работает, это очень хорошо (должно работать, поскольку XML выглядит довольно простым). К сожалению, единственный раз, когда мне это было нужно, это не сработало, я получил нарушения доступа! (т.е. ошибки в самом мастере). В итоге я накатил своего собственного волшебника ... +1. - person Cosmin Prund; 30.03.2011
comment
@Cosmin: в какой версии Delphi вы его использовали? Что это был за XSD? Вы не можете сопоставить весь XSD / XML со всеми языками, но большинство мастеров довольно далеко. Пространства имен и включение / импорт обычно значительно усложняют задачу, поэтому многие импортеры отказываются от этого. - person Jeroen Wiert Pluimers; 31.03.2011

Теперь вам нужно проанализировать XML-файл. В простейшем случае (вы знаете теги XML) это могло бы выглядеть так:

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;
person kludg    schedule 30.03.2011
comment
Это решение работает, если узел находится на самом верхнем уровне. Мне нужен узел на 3 или 4 уровня ниже. Сегодня утром я не осознавал этого, поэтому обновил свой вопрос. - person Pieter van Wyk; 30.03.2011