2011-03-30 166 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