【问题标题】:XML parsing in Android, IXMLDOMDocumentAndroid中的XML解析,IXMLDOMDocument
【发布时间】:2017-02-21 12:35:41
【问题描述】:

我在解析 XML 时遇到问题。 我设法进入“TXMLDocument”,但它在 Android 上不起作用。

如何获取字段值? 我需要拨打 9240-221 我需要值:“9240-221”

我在 Google 中没有找到如何操作(也没有找到关于如何使用 IXMLDOMDocument 的手册)。

代码:

uses ComObj, MSXML;


procedure TForm2.Button1Click(Sender: TObject);
var
  xml: IXMLDOMDocument;
  node: IXMLDomNode;
  nodes_row, nodes_se: IXMLDomNodeList;
  i, j: Integer;
  url: string;
begin

  // put url or file name
  //url := 'https://reverse.geocoder.cit.api.here.com/6.2/reversegeocode.xml?prox=32.791288%2C-17.045887&mode=retrieveAddresses&maxresults=1&gen=8&app_id=ZHsaRDKOhKQKjKOba0cS&app_code=RPlNCmcST6RICWUMk2OzYQ';

  xml := CreateOleObject('Microsoft.XMLDOM') as IXMLDOMDocument;
  xml.async := False;
  //xml.load(url); // or use loadXML to load XML document using a supplied string
  xml.loadXML
   (
    '<ns2:Search xmlns:ns2="http://www.navteq.com/lbsp/Search-Search/4">'+
    '<Response>'+
    '<MetaInfo>...</MetaInfo>'+
    '<View xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:SearchResultsViewType"> '+
    '<ViewId>0</ViewId>'+
    '<Result>'+
    '<Relevance>1.0</Relevance>'+
    '<Distance>-1996.0</Distance>'+
    '<Direction>358.6</Direction>'+
    '<MatchLevel>city</MatchLevel>'+
    '<MatchQuality>...</MatchQuality>'+
    '<Location>'+
    '<LocationId>NT_yT.xGXLRj-bHQLe8aMmP2A</LocationId>'+
    '<LocationType>area</LocationType>'+
    '<DisplayPosition>...</DisplayPosition>'+
    '<MapView>...</MapView>'+
    '<Address>'+
    '<Label>São Vicente, Portugal</Label>'+
    '<Country>PRT</Country>'+
    '<County>Ilha da Madeira</County>'+
    '<City>São Vicente</City>'+
    '<PostalCode>9240-221</PostalCode> '+
    '<AdditionalData key="CountryName">Portugal</AdditionalData>'+
    '<AdditionalData key="CountyName">Ilha da Madeira</AdditionalData>'+
    '</Address>'+
    '<MapReference>...</MapReference>'+
    '</Location> '+
    '</Result>'+
    '</View>'+
    '</Response>'+
    '</ns2:Search>'
  );

  if xml.parseError.errorCode <> 0 then
    raise Exception.Create('XML Load error:' + xml.parseError.reason);


  nodes_row := xml.selectNodes('/ns2');
  for i := 0 to nodes_row.length - 1 do
  begin
    node := nodes_row.item[i];
    showmessage('phrase=' + node.selectSingleNode('ViewId').text);
    nodes_se := node.selectNodes('.....');
    for j := 0 to nodes_se.length - 1 do
    begin
      node := nodes_se.item[j];
    end;
    showmessage('--------------');
  end;
end;

【问题讨论】:

  • IXMLDOMDocument 是一个 Windows XML Parser 对象的接口(参见msdn.microsoft.com/en-us/library/windows/desktop/…)。您为什么希望在 Android 上使用它?
  • 在“Embarcadero RadStudio 10.1Berlin - Delphi”中为 windows 编译时我可以使用“TXMLDocument”获得“PostalCode”,但在 Android 上执行“X:= TXMLDocument.Create (self);运行时它给出了一个错误,我无法获得该值。所以我试图找出另一种获取它的方法。
  • @MartynA:OmniXML 供应商是跨平台的。
  • @whosrdaddy:当然,我在评论对 IXMLDOMDocument 的引用是因为 MSXML 在代码的 Uses 子句中(更不用说 ComObj)。
  • @MartynA,哦,我现在明白了,没看代码,他在问题中提到了TXmlDocument :)

标签: android xml delphi delphi-10.1-berlin


【解决方案1】:

如果您想要 XML 文档的跨平台支持,您可以使用 TXmlDocument 并将供应商设置为 OmniXML。来自documentation(强调我的):

MSXML:最快的内置 RAD Studio XML 供应商。仅限窗户。 默认。对于跨平台支持,您必须选择不同的 XML 小贩。如果您没有指定不同的 XML 供应商,您的应用程序 在 Windows 以外的其他平台上不支持 XML,您会看到 当您在其他平台上运行应用程序时出现运行时异常。

OmniXML :比 ADOM 快得多,但比 MSXML 稍慢。 跨平台

ADOM :比其他内置 RAD Studio XML 供应商慢。 跨平台

这是一个使用 OmniXML 并且适用于所有平台的解决方案的完整示例(您至少需要 Delphi XE7):

unit FrmMain;

interface

uses
  Xml.Xmldom,
  Xml.Omnixmldom,
  Xml.Xmldoc,
  Xml.Xmlintf,
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function selectNode(xnRoot: IXmlNode; const nodePath: WideString): IXmlNode;
var
  intfSelect : IDomNodeSelect;
  dnResult : IDomNode;
  intfDocAccess : IXmlDocumentAccess;
  doc: TXmlDocument;
begin
  Result := nil;
  if not Assigned(xnRoot) or not Supports(xnRoot.DOMNode, IDomNodeSelect, intfSelect) then
    Exit;
  dnResult := intfSelect.selectNode(nodePath);
  if Assigned(dnResult) then
  begin
    if Supports(xnRoot.OwnerDocument, IXmlDocumentAccess, intfDocAccess) then
      doc := intfDocAccess.DocumentObject
    else
      doc := nil;
    Result := TXmlNode.Create(dnResult, nil, doc);
  end;
end;

function XPathQuery(Doc : IXMLDocument; Query : String) : String;

var
 Node : IXMLNode;

begin
 Result := '';
 Node := SelectNode(Doc.DocumentElement, Query);
 if Assigned(Node) then
  Result := Node.Text
end;

procedure TForm1.Button1Click(Sender: TObject);

var
  Xml: IXMLDocument;
  Str : String;

begin
 DefaultDOMVendor := sOmniXmlVendor;
 Xml := TXMLDocument.Create(nil);
 Xml.LoadFromXML
   (
    '<ns2:Search xmlns:ns2="http://www.navteq.com/lbsp/Search-Search/4">'+
    '<Response>'+
    '<MetaInfo>...</MetaInfo>'+
    '<View xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:SearchResultsViewType"> '+
    '<ViewId>0</ViewId>'+
    '<Result>'+
    '<Relevance>1.0</Relevance>'+
    '<Distance>-1996.0</Distance>'+
    '<Direction>358.6</Direction>'+
    '<MatchLevel>city</MatchLevel>'+
    '<MatchQuality>...</MatchQuality>'+
    '<Location>'+
    '<LocationId>NT_yT.xGXLRj-bHQLe8aMmP2A</LocationId>'+
    '<LocationType>area</LocationType>'+
    '<DisplayPosition>...</DisplayPosition>'+
    '<MapView>...</MapView>'+
    '<Address>'+
    '<Label>São Vicente, Portugal</Label>'+
    '<Country>PRT</Country>'+
    '<County>Ilha da Madeira</County>'+
    '<City>São Vicente</City>'+
    '<PostalCode>9240-221</PostalCode> '+
    '<AdditionalData key="CountryName">Portugal</AdditionalData>'+
    '<AdditionalData key="CountyName">Ilha da Madeira</AdditionalData>'+
    '</Address>'+
    '<MapReference>...</MapReference>'+
    '</Location> '+
    '</Result>'+
    '</View>'+
    '</Response>'+
    '</ns2:Search>'
  );
  Str := XPathQuery(Xml, '//PostalCode');
  ShowMessage(Str);
end;

end.

【讨论】:

  • 我定义了 TXMLDocument 和你说话。设置DOMVendor 以使用OmniXML。 Xml: = TXMLDocument.Create (nil); Xml.DOMVendor := GetDOMVendor ('Omni XML');它工作正常,非常感谢。再次感谢您,并对长时间的回复感到抱歉。
猜你喜欢
  • 2013-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-06
  • 2020-07-23
  • 2011-04-16
相关资源
最近更新 更多