2011-03-30 96 views
3

我是XML新手,我们需要使用新的Bing Spatial Data API进行GeoCoding。我设法以xml格式从他们那里得到一个结果。我将如何阅读响应中的特定元素,即。链接,状态和ErrorMessages?delphi读取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。

问候,彼得

+0

请添加一个关于Bing Spatial Data API的标签。 – 2011-03-30 16:14:13

回答

6

如何使用一些简单的XPATH获取所需的值?

//Link[1]/node() - 从整个文档中选择第一个“链接”节点,然后选择任何类型的第一个子节点。只是碰巧第一个子节点是包含实际的https链接的未命名节点。

假设XML文档装入Doc: TXMLDocument,你可以用这个代码提取链接:

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

您可以找到有关XPath的reading those XPath Examples on MSDN一些文档。你可能会发现更好的文档at w3schools。而且,最这一切,这是一个使用XPath来提取和显示3个请求的值的简单(但完整)的控制台应用程序

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. 
+1

+1使用XPath。 – RRUZ 2011-03-30 14:10:49

+0

现在我不必担心递归搜索xml文件中的元素。我可以使用查询来获得我想要的!谢谢。 – 2011-03-31 06:37:53

+0

对于XPath,您需要非常小心安装了Microsoft DOM。旧版本仅部分支持XPath语言,并为数组中的第一个元素使用不同的偏移量。当你使用通用的GUID来获取底层DOM对象(大多数代码都是这样做的)时,你不知道你得到了哪个DOM版本。我在这几个客户中被他们承认会得到一个完全最新的测试系统,而这只是一个没有更新的普通的Windows 2003盒子。 – 2011-04-01 07:34:36

3

现在你应该解析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; 
+0

如果节点处于最高级别,则此解决方案有效。我需要的节点是3或4个级别。我今天早上一开始并没有意识到,所以我现在已经更新了我的问题。 – 2011-03-30 15:22:21

3

如果XML的结构是相当稳定的,你可以使用XML绑定工具来生成普通德尔福类访问XML的文件。请参阅this page

3

既然有一个XML Schema for these Bing Spatial Data Services,走最简单的方法是导入使用Delphi XML Data Binding Wizard,然后使用生成的Delphi类和接口从XML中获取数据,或者将数据放入XML中。

这与Jørn E. Angeltveit建议的类似,但his suggestion使用纯XML来生成类。
如果您没有架构,那么可以,但是当您有架构时,最好导入架构。

有关使用Delphi XML Data Binding Wizard的许多示例,请首先从那里开始。

如果您需要关于绑定的帮助:请在这里提出一个新的具体问题。

+0

对于OP,值得给绑定向导一个镜头,如果它工作的非常好(应该工作,因为XML看起来很简单)。不幸的是,我唯一需要的时间没有工作,我会得到访问违规! (即:向导本身中的错误)。我结束了自己的向导...... +1。 – 2011-03-30 09:14:13

+0

@Cosmin:你使用Delphi的哪个版本?是什么XSD?您无法将所有XSD/XML映射到所有语言,但大多数向导都相当远。命名空间和包含/导入通常会让它变得更加困难,所以很多进口商都会这么做。 – 2011-03-31 09:04:03