在 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 作为其供应商库时,有一种方法可以从 Delphi 的 TXMLDocument 获取 IXMDOMLDocument 接口,以防您出于某种原因想要使用 TXMLDocument。如果我能提醒自己怎么做,我会在稍后更新。
最后,您可以避免使用 IXmlDOMDocument 和 IXDOMNodeList 接口并将它们替换为 OleVariants 并省略对 MSXML 的 Uses 引用,因为下面的代码通过后期绑定访问 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