Delphi: How to query XML DOM with XPath

example.xml


<?xml version="1.0" encoding="UTF-8" ?>
<StockHoldings>
   <Stock exchange="NASDAQ">
      <name>Borland</name>
      <price>15.375</price>
      <symbol>BORL</symbol>
      <shares>100</shares>
   </Stock>
   <Stock exchange="NYSE">
      <name>Pfizer</name>
      <price>42.75</price>
      <symbol>PFE</symbol>
      <shares type="preferred">25</shares>
   </Stock>
</StockHoldings>

Object Pascal

Using Microsoft implemenation units and types: Winapi.msxml, Winapi.ActiveX, IXMLDOMDocument3, IXMLDOMNodeList, CoDOMDocument60


program DEMO_XML_XPath;

{ Demo how to use XPath }

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  Winapi.msxml, Winapi.ActiveX;

const
  xml_file = 'example.xml';

var
  xml: IXMLDOMDocument3;
  nodes: IXMLDOMNodeList;
  i: cardinal;

begin
  try

    CoInitialize(nil);

    xml := CoDOMDocument60.Create;
    if not xml.load(xml_file) then
      raise Exception.Create(Format('Reason=%s; Line=%d; Line Position=%d, File Position=%d, Source=%s ',
        [Trim(xml.parseError.reason), xml.parseError.line, xml.parseError.linepos,
        xml.parseError.filepos, xml.parseError.srcText]));

    writeln('select elements:');
    nodes := xml.selectNodes('/StockHoldings/Stock/name');
    for i := 0 to nodes.length - 1 do
      writeln(nodes[i].text);


    writeln(sLineBreak + 'select attributes:');
    nodes := xml.selectNodes('//Stock/@exchange');
    for i := 0 to nodes.length - 1 do
      writeln(nodes[i].text);

  except
    on E: Exception do
      writeln(E.ClassName, ': ', E.Message);
  end;

  readln;

end.

Output

select elements:
Borland
Pfizer

select attributes:
NASDAQ
NYSE