delphi - 使用 XPath 从 XML 读取不同的值

标签 delphi delphi-2010 delphi-2007

我有一个以下格式的 XML:

<Accounts>
   <Account Number="1"   DebitAmount="1000" Amount="2827561.95" /> 
   <Account Number="225" DebitAmount="2000"  Amount="12312.00" /> 
   <Account Number="236" DebitAmount="London"    Amount="457656.00" /> 
   <Account Number="225" DebitAmount="London"    Amount="23462.40" /> 
   <Account Number="236" DebitAmount="Bangalore" Amount="2345345.00" /> 
</Accounts>

如何使用 Xpath 检索唯一帐号?即,我想获取值 1、225 和 236。

这就是我所做的:(我正在使用 Delphi 2007...)

Const XmlStr =
' <Accounts>
   <Account Number="1"   DebitAmount="1000" Amount="2827561.95" /> 
   <Account Number="225" DebitAmount="2000"  Amount="12312.00" /> 
   <Account Number="236" DebitAmount="London"    Amount="457656.00" /> 
   <Account Number="225" DebitAmount="London"    Amount="23462.40" /> 
   <Account Number="236" DebitAmount="Bangalore" Amount="2345345.00" /> 
</Accounts>';

 function GetAccountNumbers:TList;
 Var
   XMLDOMDocument  : IXMLDOMDocument;
   accounts : IXMLDOMNodeList;
  accountdetail :IXMLDOMNode;
   i:Integer
   list :TList
 begin
   Result:=TList.Create;
   XMLDOMDocument:=CoDOMDocument.Create;
   XMLDOMDocument.loadXML(XmlStr);
   accounts:= XMLDOMDocument.SelectNodes(''./Accounts 
  /Account[not(@Number=preceding-sibling/ Account /@Number)]');
  for i := 0 to accountdetails.length - 1 do begin
     accountdetail := accountdetails.item[i];
     //omitting the "<>nil" checks...
     list.Add(accountdetail.attributes.getNamedItem('Number').Nodevalue;
  end;
 end;

但这不会返回任何节点(accountdetails.length=0)。请让我知道我在这里缺少什么。

谢谢

普拉迪普

最佳答案

Delphi 2007 的 MSXML 版本似乎不支持 XPath 轴。因此,如果您决定使用以下代码,请先导入 Microsoft XML, v3.0Microsoft XML, v6.0 类型库,然后尝试以下操作:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, MSXML2_TLB;

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

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  XMLString =
    '<Accounts>' +
    '<Account Number="1" DebitAmount="1000" Amount="2827561.95"/>' +
    '<Account Number="225" DebitAmount="2000"  Amount="12312.00"/>' +
    '<Account Number="236" DebitAmount="London" Amount="457656.00"/>' +
    '<Account Number="225" DebitAmount="London" Amount="23462.40"/>' +
    '<Account Number="236" DebitAmount="Bangalore" Amount="2345345.00"/>' +
    '</Accounts>';

type
  TIntegerArray = array of Integer;

function GetAccountNumbers(const AXMLString: string): TIntegerArray;
var
  I: Integer;
  XMLDOMNodeList: IXMLDOMNodeList;
  XMLDOMDocument: IXMLDOMDocument3;
begin
  XMLDOMDocument := CoDOMDocument60.Create;
  if Assigned(XMLDOMDocument) and XMLDOMDocument.loadXML(AXMLString) then
  begin
    XMLDOMNodeList := XMLDOMDocument.selectNodes('/Accounts/Account[not(@Number=preceding-sibling::Account/@Number)]/@Number');
    SetLength(Result, XMLDOMNodeList.length);
    for I := 0 to XMLDOMNodeList.length - 1 do
      Result[I] := XMLDOMNodeList.item[I].nodeValue;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;
  I: Integer;
  IntegerArray: TIntegerArray;
begin
  S := 'Account numbers: ';
  IntegerArray := GetAccountNumbers(XMLString);
  for I := 0 to Length(IntegerArray) - 1 do
    S := S + IntToStr(IntegerArray[I]) + ', ';
  Delete(S, Length(S) - 1, 2);
  ShowMessage(S);
end;

end.

关于delphi - 使用 XPath 从 XML 读取不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10893919/

相关文章:

delphi - 如何确保对话框始终位于主窗口的前面

delphi - 有没有办法在还没有添加 child 时显示 TTreeNode 的 > 标志?

sql-server - 为什么只有部分用户收到错误 : "Connection is busy with results for another command"

android - MultiView 首秀,FPS 很低的动画

delphi - 适用于 Delphi 2010 的 Amazon S3 组件

delphi - 如何在此 Raise Exception 调用中摆脱 "W1047 Unsafe code ' @ operator'"

delphi - 迭代成员变量

delphi - 将 RTF 文本从数据库加载到 TRichEdit

delphi - Delphi Prism 是 Delphi .net 的新版本吗?

delphi - 无法在Win7 64位上使用Delphi 2007