Search code examples
msxmlmsxml6

Some files have 'XMLNS' listed, others just 'XSI'. How do I set an alias for the xpath query that will work with either?


Some files I need to process have this (called the "haves"):

<ApolloDataSet xmlns="http://irisoft.com/ApolloDataSet1.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

Other files in the same group have this (called the "have-nots"):

<ApolloDataSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">  

I can set the default namespace for xpath with the below:

.setProperty "SelectionNamespaces", "xmlns:a='http://irisoft.com/ApolloDataSet1.xsd'"

That works for the haves, like a:/Element, but not the have-nots, since the xpath doesn't have the a: alias.

I tried removing the xmlns attribute before processing, in the hopes that I could just use an unaliased path for both, like /Element, but that only worked for the have-nots (the haves just returned nothing).

So is there a way to process both using the same alias, or no alias? I'm trying to either use the same alias for every file, regardless of "xmlns" being listed, or use no alias for either.


Solution

  • Well I resigned to using the workaround I was trying to avoid. But here is an option for this situation until I find a better one. (And forgot to mention - using VBA for this.)

    After the domDocument is loaded, I use the getAttribute method to check if the "xmlns" attribute value is null. If it is I form the xpath string with no alias by means of a vbnullstring, which means the xpath query works with the have-not files (i.e. those files with no "xmlns" listed). If it is not null, I use the "xmlns" value to build a string for the setProperty method setting the "SelectionNamespaces" secondary property.

    If IsNull(xPOG.DocumentElement.getAttribute("xmlns")) Then
        strAlias = vbNullString
    Else
        strAlias = "a:"
        xPOG.setProperty "SelectionNamespaces", _
        "xmlns:" & Mid(strAlias, 1, 1) & "='" & xPOG.DocumentElement.getAttribute("xmlns") & "'"
    End If
    

    And the resulting processing takes on a rather ugly form of string building that I hoped to avoid. It sets an IXMLDOMNode to the nodes returned from a selectnodes method using the xPath query with the strAlias variable.

    Set xProducts = xPOG.SelectNodes("/" & strAlias & "ApolloDataSet/" _
                                    & strAlias & "Products/" _
                                    & strAlias & "Product/" _
                                    & strAlias & "PR_UPC")
    

    It isn't that it is bad, it just seems to lack elegance & remind me of how little I know sometimes. Which leads me to believe I'm missing some concept that could correct this. But it works, so I'll follow up if I find a better. I did find a kb article that touched on some of the concepts if it helps anyone. I'm using 6.0 though, so good conceptual explanation, just not exactly what I needed.

    PRB: MSXML 4.0 Sets the XML Namespace Attribute to an Empty Value for Child Nodes