0

I have an XML file and I want to find the node MessageSenderCode and read the value 1VOC. How can I do it?

<?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>
J...
  • 30,968
  • 6
  • 66
  • 143

1 Answers1

2

In a Windows app, probably the simplest way is to use the XPath feature of the OS's built-in XML DOM parser. XPath is a standard method of querying XML documents to extract information from them and is much more flexible, concise and less fiddly than the searching possible with Delphi's TXMLDocument, ime.

Delphi comes with a type library import for the Windows XML DOM parser in the unit MSXML.

To get you started, below is a minimalist XPath VCL project + DFM.

Be aware that like XML, XPath is case sensitive; don't forget that when setting up an XPath query.

Btw, the XML you posted wasn't correctly formed as far as I could see - it was lacking closing tags for ie:BodyMessage and CD815A; which I've corrected in the DFM below.

Also BTW, I seem to recall there's a way of getting at the IXMDOMLDocument interface from Delphi's TXMLDocument when you use MSXML as its vendor lib, in case you want to use TXMLDocument for some reason. If I can remind myself how to do it, I'll update this later.

Finally, you could avoid using the IXmlDOMDocument and IXDOMNodeList interfaces and replace them by OleVariants and omit the Uses reference to MSXML, because the code below accesses the MS XML DOM object via late-binding. I included the MSXML unit because I find it handy as a quick reference, and the IDE can use it for Code Completion.

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
MartynA
  • 30,454
  • 4
  • 32
  • 73