Delphi7 - OmniXML - 选择具有多个参数的特定节点

时间:2016-02-02 14:37:14

标签: delphi omnixml

XML文件:

field[name='Email']

在我的XML文件中,我有重复的节点<Partner> ... </Partner> <Partner> <K1>10</K1> <K2>3</K2> <K3>5254304</K3> <K4>test name</K4> <K5>637.51</K5> <K6>159.38</K6> <K7>802.39</K7> <K8>0.00</K8> <K9>802.39</K9> <Invoices> <Invoice> <R1>1</R1> <R2>4-02R0113-12</R2> <R3>2014-12-29</R3> <R4>2014-12-29</R4> <R5>398</R5> <R6>637.51</R6> <R7>159.38</R7> <R8>802.39</R8> <R9>0.00</R9> <R10>802.39</R10> </Invoice> </Invoices> </Partner> <Partner> ... </Partner> 。每个合作伙伴都有自己的标识号,用节点<Partner>编写。

每个合作伙伴都可以有多张发票。

我需要在发票中的<K3><R6>中查找和阅读值 我知道<R7><R2><R3>的价值。

如何搜索特定的发票,其中搜索条件为合作伙伴的多个字段<R8><R2><R3>,其中搜索条件为字段<R8>并获取字段值<K3><R6>

如何向<R7>添加多个条件?

我的代码:

SelectSingleNode

3 个答案:

答案 0 :(得分:0)

鉴于上面的例子,你可以做以下几点:

//Partner[K2=3]/Invoices/Invoice[R1=1 and R5=398]

这得到K2 = 3的伙伴的Ivoices,其中ivoices具有r1和r5的特定值。然后,根据您需要如何处理符合这些条件的发票(例如,如果有多个发票),您可以使用XPath表达式(如sum或其他)返回从这些Invoice元素计算的单个值。

答案 1 :(得分:0)

相应的OmniXMLXPath.pas文件,OmniXML不支持XPath中的逻辑操作。因此,您无法同时搜索2个以上的属性。

您可以通过调用 SelectNodes(&#39; //合作伙伴[K3 = 5254304] /发票/发票[R2 =&#39; 4-02R0113-12&#39;])来选择多个节点并通过其他属性检查节点。

如果可以,也可以使用MSXML解析器(OmniXML_MSXML单元)。这将适用于您的演示数据:

procedure TForm1.Button1Click(Sender: TObject);
var
  xml: IXMLDocument;
  iNodePartner: IXMLNode;
begin
  xml := CreateXMLDoc;
  xml.Load('c:\test.xml');
  iNodePartner := XML.selectSingleNode('//Partner[K3=5254304]/Invoices/Invoice[R2=''4-02R0113-12'' and R8=''802.39'']');
  if iNodePartner = nil then
    MessageDlg('Not found',mterror,[mbok],0);
end;

答案 2 :(得分:0)

OmniXMLXPath不支持开箱即用。但是,我在去年增加了对连续过滤器的支持,但忘记将更改推送到公共站点:(

使用更新版本,这将有效:

program Project29;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  OmniXML,
  OmniXMLXpath,
  OmniXMLUtils;

var
  xml: IXMLDocument;
  node: IXMLNode;

begin
  xml := CreateXMLDoc;
  if XMLLoadFromFile(xml, 'c:\0\partner.xml') then begin
    node := xml.SelectSingleNode('//Partner/Invoices/Invoice[R2="4-02R0113-12"][R3="2014-12-29"][R8="802.39"]');
    if not assigned(node) then
      Writeln('not found')
    else begin
      Writeln('R6=', GetNodeTextStr(node, 'R6', ''));
      Writeln('R7=', GetNodeTextStr(node, 'R7', ''));
    end;
  end;
  Readln;
end.

目前,您可以在这里获得新鲜的OmniXMLXPath.pashttps://www.dropbox.com/s/nnvrz6wnmnpmxzn/OmniXMLXPath.pas