Search code examples
xmlnamespacesvisual-foxproprefixxmldom

Change the namespace prefix of XML elements using Microsoft.xmldom in order to utilize GetElementsByTagName


While consuming an XML object, I am required to anticipate the namespace prefixes being used to be different from time to time (the 3P is notorious for this, sometime not even including the prefix in every element and letting it be implied by its parent). I understand how to get around this in .NET, but this project requires me to use VFP and Microsoft.xmldom objects.

The issue is that when I use GetElementsByTagName, I am not finding the element if the prefix is not being used or if it has been changed:

<ExampleTag>Example</ExampleTag>

loNode = loRoot.getElementsByTagName("ns2:ExampleTag").Item(0)

And Vice-Versa:

<ns2:ExampleTag>Example</ns2:ExampleTag>

loNode = loRoot.getElementsByTagName("ExampleTag").Item(0)

I keep reading about getElementsByTagNameNS, but it always errors stating it does not evaluate to an object.

If I know the namespace URI is always going to be the same, can I not use this to my advantage and somehow ignore / change the current namespace prefixes used in the XML object?


Solution

  • You are right, if the namespace URI is always going to be the same then the actual prefixes are just fluff. The key is to set the SelectionNamespaces property.

    oDoc = createobject("MSXML2.DOMDocument.6.0")
    oDoc.setProperty("SelectionNamespaces", [xmlns:foo="] + m.cNamespaceURI + ["])
    oDoc.LoadXML(...)
    
    with oDoc.selectNodes("//foo:ExampleTag")
       ...
    endwith
    

    In this way you can select nodes based on the prefix that you chose (here foo) regardless of the actual prefixes - if any - used by your XML input.