XML parsing, TXMLDocument XML parsing, TXMLDocument xml xml

XML parsing, TXMLDocument


Try this:

uses ComObj, MSXML;procedure TForm1.Button1Click(Sender: TObject);var  xml: IXMLDOMDocument;  node: IXMLDomNode;  nodes_row, nodes_se: IXMLDomNodeList;  i, j: Integer;  url: string;begin  // put url or file name  url := 'http://softez.pp.ua/gg.xml';  xml := CreateOleObject('Microsoft.XMLDOM') as IXMLDOMDocument;  xml.async := False;  xml.load(url); // or use loadXML to load XML document using a supplied string  if xml.parseError.errorCode <> 0 then    raise Exception.Create('XML Load error:' + xml.parseError.reason);  Memo1.Clear;  nodes_row := xml.selectNodes('/doc/data/row');  for i := 0 to nodes_row.length - 1 do  begin    node := nodes_row.item[i];    Memo1.Lines.Add('phrase=' + node.selectSingleNode('phrase').text);    nodes_se := node.selectNodes('search_engines/search_engine/se_url');    for j := 0 to nodes_se.length - 1 do    begin      node := nodes_se.item[j];      Memo1.Lines.Add('url=' + node.text);    end;    Memo1.Lines.Add('--------------');  end;end;

Result:

phrase=key1url=link1_1url=link1_2--------------phrase=key2url=link2_1url=link2_2--------------

A Reference to IXMLDOMDocument


If you first include these 3 general purpose library routines ....

uses XMLDoc, XMLIntf, xmldom;function CreateXMLDocument( var Owner1: TComponent): TXMLDocument;beginOwner1 := TComponent.Create( nil);result  := TXMLDocument.Create( Owner1);result.Options := [doNodeAutoCreate, doNodeAutoIndent, doAttrNull,                   doAutoPrefix, doNamespaceDecl];result.DOMVendor := GetDOMVendor( 'MSXML');end;function XPATHSelect( const FocusNode: IXMLNode; const sXPath: string): TArray<IXMLNode>;var  DomNodeSelect: IDomNodeSelect;  DOMNode      : IDomNode;  DocAccess    : IXmlDocumentAccess;  Doc          : TXmlDocument;  DOMNodes     : IDOMNodeList;  iDOMNode     : integer;beginSetLength( result, 0);if assigned( FocusNode) and   Supports( FocusNode.DOMNode, IDomNodeSelect, DomNodeSelect) then    DOMNodes := DomNodeSelect.SelectNodes( sXPath);if not assigned( DOMNodes) then exit;SetLength( result, DOMNodes.Length);for iDOMNode := 0 to DOMNodes.Length - 1 do  begin  Doc := nil;  DOMNode := DOMNodes.item[iDOMNode];  if Supports( DOMNode, IXmlDocumentAccess, DocAccess) then    Doc := DocAccess.DocumentObject;  result[ iDOMNode] := TXmlNode.Create( DOMNode, nil, Doc) as IXMLNode;  endend;function XPATHSelectFirst( const FocusNode: IXMLNode; const sXPath: string; var SelectedNode: IXMLNode): boolean;var  DomNodeSelect: IDomNodeSelect;  DOMNode      : IDomNode;  DocAccess    : IXmlDocumentAccess;  Doc          : TXmlDocument;beginSelectedNode := nil;if assigned( FocusNode) and   Supports( FocusNode.DOMNode, IDomNodeSelect, DomNodeSelect) then  DOMNode := DomNodeSelect.selectNode( sXPath);if assigned( DOMNode) and   Supports( DOMNode.OwnerDocument, IXmlDocumentAccess, DocAccess) then  Doc := DocAccess.DocumentObject;if Assigned( DOMNode) then  SelectedNode := TXmlNode.Create( DOMNode, nil, Doc);result := assigned( SelectedNode)end;

Then A much neater solution is ...

procedure TForm2.btn1Click(Sender: TObject);const  DocumentSource =  'http://softez.pp.ua/gg.xml';var  Doc: IXMLDocument;  DocOwner: TComponent;  RowNode, PhraseNode, UrlNode: IXMLNode;  procedure PutLn( const LineFmt: string; const Args: array of const);  begin  memo2.Lines.Add( Format( LineFmt, Args))  end;beginmemo2.Clear;Doc := CreateXMLDocument( DocOwner);Doc.LoadFromFile( DocumentSource);for RowNode in XPATHSelect( Doc.DocumentElement, '//row[phrase]') do  begin  if not XPATHSelectFirst( RowNode, 'phrase', PhraseNode) then continue;  PutLn( 'phrase=%s', [PhraseNode.NodeValue]);  for UrlNode in XPATHSelect( RowNode, 'search_engines/search_engine/se_url') do    PutLn( 'url=%s', [UrlNode.NodeValue]);  PutLn('--------------',[])  end;DocOwner.Free;end;

This was tested on Delphi 2010 and works a treat.


And just for good measure, here is another answer, provided you are not afraid to mix in a little XSLT !

const Transform ='<?xml version="1.0" encoding="utf-8"?>' +'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> ' +' <xsl:output method="text" indent="no"/>' +' <xsl:template match="text()|@*"/>' +' <xsl:template match="//row">' +'  <xsl:text>phrase=</xsl:text>' +'  <xsl:value-of select="phrase"/>' +'  <xsl:text>&#10;</xsl:text>' +'  <xsl:apply-templates/>' +'  <xsl:text>--------------&#10;</xsl:text>' +' </xsl:template>' +' <xsl:template match="search_engines/search_engine/se_url">' +'  <xsl:text>url=</xsl:text>' +'  <xsl:value-of select="."/>' +'  <xsl:text>&#10;</xsl:text>' +' </xsl:template>' +'</xsl:stylesheet>';procedure TForm2.btn1Click( Sender: TObject);const  DocumentSource =  'http://softez.pp.ua/gg.xml';var  Doc, Style: IXMLDocument;  DocOwner, StyleOwner: TComponent;  sOut: widestring;begin  memo2.Clear;  Doc := CreateXMLDocument( DocOwner);  Doc.LoadFromFile( DocumentSource);  Style := CreateXMLDocument( StyleOwner);  Style.LoadFromXML( Transform);  Doc.DocumentElement.TransformNode( Style.DocumentElement, sOut);  memo2.Lines.Add( sOut);  DocOwner.Free;    StyleOwner.Freeend;