如何查找Xml节点或元素

时间:2014-07-17 15:02:18

标签: xml delphi delphi-2010

我有一个XML文件,我想找到节点MessageSenderCode并读取值1VOC。我该怎么办?

<?xml version="1.0" encoding="utf-8"?>
<CD815A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:emcs="http://emcs.dgtaxud.ec/v10/types" xmlns:tms="http://emcs.dgtaxud.ec/v10/tms" xmlns:tlc="http://emcs.dgtaxud.ec/v10/tlc" xmlns:doc="http://emcs.dgtaxud.ec/v10/doc" xmlns:ie="http://emcs.dgtaxud.ec/v10/cd815/ie" xsi:schemaLocation="ie815.xsd">
    <tms:HeaderMessage>
        <tms:MessageSenderCode>1VOC</tms:MessageSenderCode>
        <tms:OfficeReserved/>
        <tms:FlowName>1VOC20140716_C04.xml</tms:FlowName>
        <tms:OfficeReserved/>
        <tms:OfficeCode>134000</tms:OfficeCode>
        <tms:OfficeReserved/>
        <tms:VATAutorizedSender>00701720260</tms:VATAutorizedSender>
        <tms:OfficeNumberAutorizedSender>001</tms:OfficeNumberAutorizedSender>
        <tms:OfficeReserved/>
        <tms:RecordFlowNumber>4</tms:RecordFlowNumber>
    </tms:HeaderMessage>
    <ie:BodyMessage>
        <ie:SubmittedDraftOfEaad>
            <tms:Header>
                <tms:MessageCode>IE815</tms:MessageCode>
                <tms:DeclaratorIdentifyCode>IT00TVA00042S</tms:DeclaratorIdentifyCode>
                <tms:IdentifyDraftCode>159/2013</tms:IdentifyDraftCode>
                <tms:TransmissionFileDate>20140716</tms:TransmissionFileDate>
                <tms:RecordType>A</tms:RecordType>
                <tms:RecordNumberInFile>0001</tms:RecordNumberInFile>
                <tms:RecordNumberFile>0001</tms:RecordNumberFile>
                <tms:TotalRecordB>00</tms:TotalRecordB>
                <tms:TotalRecordC>002</tms:TotalRecordC>
                <tms:SubmissionMessageType>1</tms:SubmissionMessageType>
            </tms:Header>

1 个答案:

答案 0 :(得分:2)

在Windows应用程序中,最简单的方法可能是使用操作系统内置XML DOM解析器的XPath功能。 XPath是查询XML文档以从中提取信息的标准方法,并且比使用Delphi的TXMLDocument,ime进行搜索更加灵活,简洁且不那么繁琐。

Delphi附带了MSXML单元中Windows XML DOM解析器的类型库导入。

为了帮助您入门,下面是一个极简主义的XPath VCL项目+ DFM。

请注意,与XML一样,XPath区分大小写;在设置XPath查询时不要忘记。

顺便说一句,就我所见,你发布的XML没有正确形成 - 它缺少关闭标签:ie:BodyMessage和CD815A;我在下面的DFM中已经纠正过。

同样顺便说一句,我似乎记得当你使用MSXML作为它的供应商lib时,有一种从Delphi的TXMLDocument获取IXMDOMLDocument接口的方法,以防你出于某种原因想要使用TXMLDocument。如果我能提醒自己该怎么做,我稍后会更新。

最后,您可以避免使用IXmlDOMDocument和IXDOMNodeList接口并将其替换为OleVariants并省略对MSXML的使用引用,因为下面的代码通过后期绑定访问MS XML DOM对象。我包含了MSXML单元,因为我发现它很方便作为快速参考,IDE可以将它用于代码完成。

unit XPathu;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComObj, MSXML;
[...]

procedure TForm1.btnFindClick(Sender: TObject);
var
  XmlDoc: IXmlDOMDocument;
  NodeList : IXmlDOMNodeList;
  Value : String;
  I : Integer;
begin
  Memo2.Lines.Clear;
  XmlDoc := CreateOleObject('Microsoft.XMLDOM') as IXMLDOMDocument;  // or := CoDOMDocument.Create;  // for early binding
  XmlDoc.Async := False;
  XmlDoc.LoadXML(Memo1.Lines.Text);
  if xmlDoc.parseError.errorCode <> 0 then
    raise Exception.Create('XML Load error:' + xmlDoc.parseError.reason);

  //  by default, edPathQuery.Text is set to '/CD815A/tms:MessageSenderCode'
  NodeList := XmlDoc.documentElement.SelectNodes(edPathQuery.Text);
  for I := 0 to NodeList.Length - 1 do begin
    Value := NodeList.item[I].text;
    Memo2.Lines.Add(Format('%d: %s', [I, Value]));
  end;
end;

end.

DFM

object Form1: TForm1
  Left = 195
  Top = 124
  Width = 559
  Height = 430
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Memo1: TMemo
    Left = 7
    Top = 8
    Width = 529
    Height = 161
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'Courier New'
    Font.Style = []
    Lines.Strings = (
      '<?xml version="1.0" encoding="utf-8"?>'
      '<CD815A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '
      'xmlns:emcs="http://emcs.dgtaxud.ec/v10/types" '
      'xmlns:tms="http://emcs.dgtaxud.ec/v10/tms" '
      'xmlns:tlc="http://emcs.dgtaxud.ec/v10/tlc" '
      'xmlns:doc="http://emcs.dgtaxud.ec/v10/doc" '
      'xmlns:ie="http://emcs.dgtaxud.ec/v10/cd815/ie" '
      'xsi:schemaLocation="ie815.xsd">'
      '    <tms:HeaderMessage>'
      '        <tms:MessageSenderCode>1VOC</tms:MessageSenderCode>'
      '        <tms:OfficeReserved/>'
      '        <tms:FlowName>1VOC20140716_C04.xml</tms:FlowName>'
      '        <tms:OfficeReserved/>'
      '        <tms:OfficeCode>134000</tms:OfficeCode>'
      '        <tms:OfficeReserved/>'

        '        <tms:VATAutorizedSender>00701720260</tms:VATAutorizedSen' +
        'der>'
      '        '

        '<tms:OfficeNumberAutorizedSender>001</tms:OfficeNumberAutorizedS' +
        'ender>'
      '        <tms:OfficeReserved/>'
      '        <tms:RecordFlowNumber>4</tms:RecordFlowNumber>'
      '    </tms:HeaderMessage>'
      '    <ie:BodyMessage>'
      '        <ie:SubmittedDraftOfEaad>'
      '            <tms:Header>'
      '                <tms:MessageCode>IE815</tms:MessageCode>'
      '                '

        '<tms:DeclaratorIdentifyCode>IT00TVA00042S</tms:DeclaratorIdentif' +
        'yCode>'

        '                <tms:IdentifyDraftCode>159/2013</tms:IdentifyDra' +
        'ftCode>'
      '                '
      '<tms:TransmissionFileDate>20140716</tms:TransmissionFileDate>'
      '                <tms:RecordType>A</tms:RecordType>'

        '                <tms:RecordNumberInFile>0001</tms:RecordNumberIn' +
        'File>'

        '                <tms:RecordNumberFile>0001</tms:RecordNumberFile' +
        '>'
      '                <tms:TotalRecordB>00</tms:TotalRecordB>'
      '                <tms:TotalRecordC>002</tms:TotalRecordC>'

        '                <tms:SubmissionMessageType>1</tms:SubmissionMess' +
        'ageType>'
      '            </tms:Header>'
      '        </ie:SubmittedDraftOfEaad>'
      '    </ie:BodyMessage>'
      '</CD815A>')
    ParentFont = False
    TabOrder = 0
  end
  object btnFind: TButton
    Left = 280
    Top = 189
    Width = 75
    Height = 25
    Caption = 'Find'
    TabOrder = 1
    OnClick = btnFindClick
  end
  object edPathQuery: TEdit
    Left = 32
    Top = 192
    Width = 233
    Height = 21
    TabOrder = 2
    Text = '/CD815A/tms:MessageSenderCode'
  end
  object Memo2: TMemo
    Left = 7
    Top = 235
    Width = 529
    Height = 148
    TabOrder = 3
  end
end