FindNode - cXMLDOMDocumentFragment

Searches an XML Document using an XPath query string returning the first matching node

Type: Function

Return Data Type: Handle

Parameters: String sQueryString

ParameterDescription
sQueryStringXPath query string


Return Value

Returns the first matching XML node or zero if none is found.


Syntax
Function FindNode String sQueryString Returns Handle

Call: Get FindNode sQueryString to HandleVariable


Description

FindNode is used search for an XML node. The starting point of the search is the XML node receiving this message. If a node is not found, it returns 0. If the node is found, the XML node must be destroyed when no longer needed.

If your query needs to return multiple matches, use FindNodeList.

The query string passed into the function is a standard XPath query string. XPath is a powerful and rich query language. A web search for "xpath xml" will provide you with the documentation needed to construct searches. You may also wish to limit your searches to Microsoft (MSDN or MSXML) as the DataFlex XML classes are based on the Microsoft XML objects.

Samples

// find first node with CUSTOMER element name
Get FindNode of hoXML "CUSTOMER" to hoNode

// find first child node of CUSTOMER with CONTACT element
Get FindNode of hoXML "CUSTOMER/CONTACT" to hoNode

// find the first descendant node with an element name of CONTACT
Get FindNode of hoXML "descendant::CONTACT" to hoNode

//In this example, we search for a child node named removeMe and remove it.
Get FindNode of hoXML "removeMe" to hoParam
If hoParam Begin
    Get Remove Node of hoXML hoParam to hoParam
    Send Destroy of hoParam
End


FindNodeList works in a similar fashion, except it returns a list of matched nodes based on the cXMLDomNodeList class. You can then use NodeListLength and CollectionNode to traverse and process these items. When the node-list object is no longer needed it must be destroyed.

Get FindNodeList of hoXML "CUSTOMER" to hoNodes
Get FindNodeList of hoXML "CUSTOMER/CONTACT" to hoNodes
Get FindNodeList of hoXML "descendant::CONTACT" to hoNodes


XPath and Namespaces

If your XML document has namespaces, the standard XPath gets complicated as the industry standards were not originally designed to search for namespaces. You need to search by the actual namespace URI and not the namespace prefix. You know what the namespace URI is (or you should), while you don't actually know what the prefix will be or if the document is using default namespaces.

As an example, all three of these fragments are the same and you would want an XPath query string to work the same with all of these.

<x:CUSTOMERLIST xmlns:x="http://www.dataaccess.com/Customer">
               <x:CUSTOMER NAME="Ming Foo Bakery">
<y:CUSTOMERLIST xmlns:y="http://www.dataaccess.com/Customer">
               <y:CUSTOMER NAME="Ming Foo Bakery">
< CUSTOMERLIST xmlns ="http://www.dataaccess.com/Customer">
               < CUSTOMER NAME="Ming Foo Bakery">


These are all the same because the namespace URI (http://www.dataaccess.com/Customer) is the same in all three and the nodes are merely defined using different prefix naming conventions. Think of the prefix (or default prefix) as being the same as a variable name. You need to know what the content of that variable is (the URI) and not the variable name.

To work around this, the MSXML control provides a way to define your own prefix/URI name for searches. This way you get to pair a known URI with a prefix of your choosing and then use that known prefix in your XPath query string. We have exposed that via the psSelectionNamespaces property.

For example, all three of these documents could be queried using:

Set psSelectionNamespaces of hoXML to "xmlns:cust='http://www.dataaccess.com/Customer' " 
Get FindNode of hoXML "cust:CUSTOMER" to hoNode
Get FindNode of hoXML "cust:CUSTOMER/cust:CONTACT" to hoNode
Get FindNode of hoXML "descendant::cust:CONTACT" to hoNode


Sample

In this example, we search for a qualified child node named removeMe in the http://www.dataaccess.com/MySchema namespace and remove it.

Handle hoParam hoParent
String sNS

Move ("xmlns:q='http://www.dataaccess.com/MySchema'" ) to sNS             
Set psSelectionNamespaces of hoXML to sNS
Get FindNode of hoXML "q:removeMe" to hoParam
If hoParam Begin
    Get ParentNode of hoParam to hoParent
    Get RemoveNode of hoParent hoParam to hoParam
    Send Destroy of hoParam
End