Welcome To The Home Of The Visual FoxPro Experts  
home. signup. forum. archives. search. google. articles. downloads. faq. members. weblogs. file info. rss.
 From: Russell Hill
  Where is Russell Hill?
 Sydney
 Australia
 Russell Hill
 To: Tom Gadue
  Where is Tom Gadue?
 
 New York - United States
 Tom Gadue
 Tags
Subject: RE: This Is An Example of Parsing XML in FoxPro
Thread ID: 89226 Message ID: 228358 # Views: 60 # Ratings: 0
Version: Visual FoxPro 9 Category: XML
Date: Monday, May 18, 2009 1:33:06 PM         
   


> I am posting the following function in hope that someone else can use it without pulling their hair out trying to figure out XML parsing. The following function just traverses a simple INI setting type XML file (you can easily tailor this to your needs). This is probably one of the more basic things you can do with the MS XML parser but my hope is that it produces a good starting point. The XMLAdapter class is not used because it was very weak for just reading values (I didn't want to use cursors at all).
>
> References for the MSXML2.DomDocument object for use in FoxPro can be found in the articles section "GETTING TO GRIPS WITH THE MICROSOFT DOM OBJECT" by Simon Arnold and an excellent reference for the DOM object in general which lists details about every attribute and every function can be found here:
>
> http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html
>
> Sample XML File ReadXML() will parse (make sure it is saved as UTF-8 format or specify "us-ascii" for a plain text file in the encoding):
>
> <?xml version="1.0" encoding="UTF-8"?>
> <system>
> <customer>
> <name my_attribute="XMLRules">XYZ Plus</name>
> <address1>777 W. N. Blvd.</address1>
> </customer>
> <settings>
> <usepw>yes</usepw>
> <reporting>no</reporting>
> </settings>
> </system>
>
>
> *******************************************************
> * ReadXML
> *
> * Read an XML file of a structured format that would
> * be similiar to an INI settings file, traverses
> * through the entire structure as an example
> *******************************************************
> FUNCTION ReadXML
>   LPARAMETERS pcXMLFile
>   LOCAL oXML, oRootNode, cParentName, cValue, cName, nType, nNumNodes, ;
>     cRootTagName, oNodeList, oNode, bHasChild, cTagName, ;
>     oChildNodeList, nChildLen, nPass, oChildNode, oAttributeList, ;
>     cTextData, nTextDataLen, cAttrName, cAttrValue, nNumAttr
> 
>   * Start out by creating the actual xml parser object
>   oXML = CREATEOBJECT('MSXML2.DomDocument')
> 
>   * Wait for the document to be parsed and loaded
>   oXML.ASYNC = .F.
> 
>   * Load the document into the object, if this was a stream instead
>   * of a file name, we would use loadXML(cCharStream)
>   oXML.LOAD(pcXMLFile)
> 
>   * Get the root element
>   oRootNode = oXML.documentElement
> 
>   * What is the root tag name?
>   cRootTagName = oRootNode.tagName
> 
>   * Get all the nodes in the document with the special '*'
>   * parameter, we could just pass in a tag name to get the
>   * node list for that specific tag
>   oNodeList = oRootNode.getElementsByTagName("*")
> 
>   * How many nodes did we retrieve
>   nNumNodes = oNodeList.LENGTH
> 
>   * Go through all the nodes in the NodeList.
>   * Note that Attribute and Character/Text Data is NOT
>   * counted as part of this list, you must get that data
>   * separately, this list only contains tag elements
>   * Note that this uses C like array positioning by
>   * starting at zero
>   FOR nPos = 0 TO (nNumNodes-1) STEP 1
>     * Get the next node in the list
>     oNode = oNodeList.ITEM(nPos)
> 
>     * What is the value of this node, if it is an element
>     * then this value is the tag name
>     cParentName = oNode.nodeName
> 
>     * Does this node have any children?
>     bHasChild = oNode.hasChildNodes()
> 
>     * What is the node type, element or text?
>     nType = oNode.nodeType
> 
>     IF nType = 1
>       * This is an element/tag so it may have
>       * attributes.  We can get those attributes
>       * by name or in a list.
>       * Since this example function traverses thru
>       * the xml tree, it would not be very efficient
>       * to query every single node for a particular
>       * attribute, this is just to show how it could
>       * be done.
> 
>       * if the attribute does not exist, returns .NULL.
>       * otherwise we get the attribute value
>       cAttrValue = oNode.getAttribute("my_attribute")
> 
>       * We could also get a NamedNodeMap accessing 
>       * the attributes property
>       oAttributeList = oNode.attributes
> 
>       * how many attributes do we have
>       nNumAttr = oAttributeList.length
> 
>       * Get the attribute using the list
>       cAttrValue = oAttributeList.getNamedItem("my_attribute")
>     ENDIF
> 
>     IF bHasChild
>       * Ok, we know we have children but what type are they?
>       * Just test the first one to see if it is something
>       * other than an element and if so, get it
>       IF oNode.firstChild.nodeType != 1
>         * We know we have something other than an element, get
>         * the tag name of the element we are parsing
>         cTagName = oNode.tagName
> 
>         * Get the node list and determine how man child
>         * nodes this element has
>         oChildNodeList = oNode.childNodes
>         nChildLen = oChildNodeList.LENGTH
> 
>         * Go through all child nodes and grab the non-element
>         * data to do with what you like
>         FOR nPass = 0 TO (nChildLen-1) STEP 1
>           oChildNode = oChildNodeList.ITEM(nPass)
>           cValue = oChildNode.nodeValue
>           cName = oChildNode.nodeName
>           nType = oChildNode.nodeType
>           bHasChild = oChildNode.hasChildNodes()
> 
>           * For now just look for text types, other
>           * types can be added later if needed
>           DO CASE
>             CASE nType = 3
>               * Text node
>               cTextData = oChildNode.DATA
>               nTextDataLen = oChildNode.LENGTH
>             CASE nType = 4
>               * CData Section node
>               cTextData = oChildNode.DATA
>               nTextDataLen = oChildNode.LENGTH
>             OTHERWISE
>               * Some other node we don't care about
>               * right now
>           ENDCASE
>         ENDFOR
>       ENDIF
>     ENDIF
>   ENDFOR
> 
>   RETURN 0
> ENDFUNC
> 


Tom,

Your ReadXML() is a very good starting point to get my head around parsing XML using the XML DOM.

I've only been playing with it for 15 minutes and have already found it more useful than most tutorials.

The reference link provided also looks useful.

If I could rate this thread I would - Eric?

Thanks!

Russell.

ENTIRE THREAD

This Is An Example of Parsing XML in FoxPro Posted by Tom Gadue @ 2/23/2006 5:22:13 PM
RE: This Is An Example of Parsing XML in FoxPro Posted by Russell Hill @ 5/18/2009 1:33:06 PM
RE: This Is An Example of Parsing XML in FoxPro Posted by Simon Arnold @ 5/19/2009 2:36:30 PM
RE: This Is An Example of Parsing XML in FoxPro Posted by Russell Hill @ 5/19/2009 2:45:13 PM
RE: This Is An Example of Parsing XML in FoxPro Posted by Jose Conyers @ 9/28/2011 6:28:33 PM
RE: This Is An Example of Parsing XML in FoxPro Posted by James Frye @ 9/28/2011 7:56:44 PM