1. Technology

Select XML Nodes Into IXMLNodeList Using XPath In Delphi's XmlDom

Get IXMLNodeList Using XPath's IDomNodeSelect

By

XPath is a language for addressing, searching, and matching pieces of (an XML) document.

XPath uses a path notation, similar to that used in file systems and URLs, to specify and match pieces of the document. For example, the XPath: /x/y/z searches the document for a root node of x, under which resides the node y, under which resides the node z. This statement returns all nodes that match the specified path structure.

In Delphi, the XPath implementation in included in the xmldom.pas unit.

If you process XML using the TXMLDocument and Microsoft's MSXML as the DOMVendor (object that represents a registered DOM implementation) you are familiar with the IXMLNode (TXMLNode) node interface. IXMLNode represents a node in an XML document.

Select Nodes By Their NodeName

The IXMLNode does not provide a method to select all the (child nodes of some parent node) nodes that have the same node name.

Let's say the task is to process all the "<name>" nodes from this XML section:

<parent>
  <name n="1">
  <surname s="2">
  <name n="1">
  <someother so="5">
  <name n="1">
  <name n="1">
  <surname s="2">
  <someother so="5">
</parent>

The IXMLNode does not have a way of selecting child nodes into a node collection by node name.

You can iterate through all the nodes and if TXMLNode.NodeName matches "name" process it.

A far better approach is to take advantage of the powerful node processing features in XPath.

Since XPath implementation of SelectNodes return IDomNodeList and we need IXMLNodeList we need to "wrap" a call to IDomNodeSelect.selectNodes into a function that will result in IXMLNodeList.

Here's the SelectNodes function resulting IXMLNodeList by wrapping a call to XPath's selectNodes:

uses xmlintf, xmldom;

class function TXMLNodeHelper.SelectNodes(xnRoot: IXmlNode; const nodePath: WideString): IXMLNodeList;
var
  intfSelect : IDomNodeSelect;
  intfAccess : IXmlNodeAccess;
  dnlResult  : IDomNodeList;
  intfDocAccess : IXmlDocumentAccess;
  doc: TXmlDocument;
  i : Integer;
  dn : IDomNode;
begin
  Result := nil;
  if not Assigned(xnRoot)
    or not Supports(xnRoot, IXmlNodeAccess, intfAccess)
    or not Supports(xnRoot.DOMNode, IDomNodeSelect, intfSelect) then
    Exit;

  dnlResult := intfSelect.selectNodes(nodePath);
  if Assigned(dnlResult) then
  begin
    Result := TXmlNodeList.Create(intfAccess.GetNodeObject, '', nil);
    if Supports(xnRoot.OwnerDocument, IXmlDocumentAccess, intfDocAccess) then
      doc := intfDocAccess.DocumentObject
    else
      doc := nil;

    for i := 0 to dnlResult.length - 1 do
    begin
      dn := dnlResult.item[i];
      Result.Add(TXmlNode.Create(dn, nil, doc));
    end;
  end;
end;
Now, select all child nodes of an XML's DocumentElement (root node) by their name:
var
  iNode : IXMLNode;
  idNodes : IXMLNodeList;
begin
  idNodes := TXMLNodeHelper.SelectNodes(SomeTXMLDocument.DocumentElement, nodeName);
  iNode := idNodes.First;
  while Assigned(iNode) do
  begin
  //process iNode...
    iNode := iNode.NextSibling;
  end;
end;
Note: Here's how to Select Single IXMLNode / TXmlNode Using XPath In Delphi's XmlDom

Note: a full examination of XPath and its usage is, of course, beyond the scope of this article.

Delphi tips navigator:
» XPath To Select Single XML Node
« Shell Folder Menu - Your Application

  1. About.com
  2. Technology
  3. Delphi
  4. Using VCL Components
  5. Select XML Nodes Into IXMLNodeList Using XPath - Delphi

©2014 About.com. All rights reserved.