0

My xml tree contains this in the structure

<foo name="bar">
    <location order="1">data1</location>
    <location order="2">data2</location>
</foo>

I'm trying to refer to anywhere in the tree where location order ="2" (there could be 1000s of them) to manipulate all data2 texts. I cannot get vba to recognize it with an xpath string assignment.

I've tried many things but the thing that makes the makes the most sense to me is

xPath = "//prefix:foo[@name='bar']/location[@order='2']" 

It does however recognize the xPath assignment to foo if I remove.

"/location[@order='2']"

Am I doing something wrong in the xpath syntax? Or is there more to assigning a path to a node containing several attributes to be selected in the tree structure?

Maybe I'm trying to use the wrong methods to access the variable?

Dim list as IXMLDOMNodeList
Set list = xDoc.SelectNodes(xPath)
Debug.Print list.length

Gives me a 0 but there are two instances of those specific nodes in my xml

Edit: Still giving me zero after doing some things with yours. Here's an example xml so you can see namespace. I can still get it to print a length if I leave out the "/location[@order='2']". Also to clarify, I only am interested in the path that is , there could be many other foo nodes with the child . These I do not care about for now.

    <?xml version="1.0" encoding="utf-8"?>
    <IPSGDatas xsi:schemaLocation="uri:mybikes:wheels MYBIKES%20WHEELS%202012.xsd" 
      xmlns="uri:mybikes:wheels" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <header>
            <language_id>120</language_id>
        </header>
        <datas>
            <good>
                <signature/>
                <bike>
                    <foos>
                        <marker>
                            <location order="1">data1</location>
                            <location order="2">data2</location>
                        </marker>
                        <foo name="bar">
                            <location order="1">data1</location>
                            <location order="2">data2</location>
                        </foo>
                    </foos>
                    <profile_id>MyName1</profile_id>
                </bike>
                <action_id>New</action_id>
                <index_id>1</index_id>
                <agency/>
                <agency_reference/>
                <accreditation_id>U</accreditation_id>
            </good>
            <good>
                <signature/>
                <bike>
                    <foos>
                        <marker>
                            <location order="1">data1</location>
                            <location order="2">data2</location>
                        </marker>
                        <foo name="bar">
                            <location order="1">data1</location>
                            <location order="2">data2</location>
                        </foo>
                    </foos>
                    <profile_id>MyName2</profile_id>
                </bike>
                <action_id>New</action_id>
                <index_id>1</index_id>
                <agency/>
                <agency_reference/>
                <accreditation_id>U</accreditation_id>
            </good>
        </datas>
    </IPSGDatas>
Community
  • 1
  • 1
Dan
  • 758
  • 6
  • 20
  • `"foo[@name='bar']/location[@order='2']" ` worked for me - but you seem to have not included some namespace in your example XML, so it's difficult to be sure. Can you maybe make it a bit more representative of your actual use case? – Tim Williams Jul 30 '17 at 20:02
  • Hmmm. Typing from my phone and working with files on a lap top without access. Give me a bit until I do and I'll see what I can do. At the moment, I can tell you the namespace works just fine without the location order="2" node. – Dan Jul 30 '17 at 20:07
  • :/ maybe I'm using the wrong methods. – Dan Jul 30 '17 at 20:17
  • I'm trying to access the variable with – Dan Jul 30 '17 at 20:17
  • Sorry I'll edit the post... – Dan Jul 30 '17 at 20:19
  • @TimWilliams, I included an example XML with namespace. I guess Im misunderstanding namespace altogether. I thought I had a handle on it a while back but its more confusing to me now. – Dan Jul 31 '17 at 01:25

1 Answers1

1

EDITED

Using your updated XML, this code gives me "data2" and "data2" as output:

Sub Tester3()

    Dim xmlDoc As New MSXML2.DOMDocument30
    Dim objNodes As IXMLDOMNodeList, o As Object

    xmlDoc.async = False
    xmlDoc.LoadXML Range("C1").Value
    xmlDoc.setProperty "SelectionLanguage", "XPath"

    '### this takes care of the namespace ###
    xmlDoc.setProperty "SelectionNamespaces", _
                     "xmlns:xx='uri:mybikes:wheels'"

    If xmlDoc.parseError.errorCode <> 0 Then

        MsgBox "Error!" & vbCrLf & _
        "  Line: " & xmlDoc.parseError.Line & vbCrLf & _
        "  Text:" & xmlDoc.parseError.srcText & vbCrLf & _
        "  Reason: " & xmlDoc.parseError.reason

    Else
        '### note: adding the namespace alias prefix defined above ###
        Set objNodes = xmlDoc.SelectNodes("//xx:foo[@name='bar']/xx:location[@order='2']")

        If objNodes.Length = 0 Then
            Debug.Print "not found"
        Else
            For Each o In objNodes
                Debug.Print o.nodeTypedValue
            Next o
        End If 'have line items

    End If 'parsed OK
End Sub

Similar Q previously: How to ignore a XML namespace

Tim Williams
  • 154,628
  • 8
  • 97
  • 125
  • Thanks for the help Tim! I didn't set he namespace prefix to "xx" although I did notice before the second attribute in the xPath string you included the prefix...so I did the same and voila! This is exactly what I was looking for and works great! Thanks again so much! – Dan Jul 31 '17 at 18:18
  • I gotta read up more on namespaces and xpath. I thought I had it down pretty good...not the case. – Dan Jul 31 '17 at 18:26