1

I am still trying to learn about NextSibling and I am using XMLHTTP in excel VBA. Here's the HTML for the element

<ul class="list-unstyled list-specification">
                                            <li><span>ID</span> <span class="text-info">22928</span></li>
                                            
                                            <li><span>Category</span> <span class="text-info">Mechanical</span></li>
                                                <li><span>Discipline</span> <span class="text-info">Mechanical  </span></li>
                                                                                            <li><span>Commodity</span> <span class="text-info">Pipe</span></li>
                                                 <li><span>Sub commodity</span> <span class="text-info">12 In Pipe </span></li>
                                                                                            <li><span>UOM</span> <span class="text-info">EA</span></li>
                                                                                              <li><span>Available quantity</span> <span class="text-info">30</span></li>
                                                                                                                                                                                                                                                                            <li><span>Age</span> <span class="text-info">8</span></li>
                                                                                        
                                        </ul>

I have used this line to spot on the first span in the li (lists) so as to identify the headers for each part

Set post = html.querySelectorAll(".list-specification li span")

Then I used loops like that

    For j = 0 To post.Length - 1
        If post.Item(j).innerText = "ID" Then
            Debug.Print post.Item(j).NextSibling.innerText
        End If
    Next j

I got an error when trying to use NextSibling. I feel stuck as for that NextSibling .. Can you guide me? for example ID is the first in the list and I would like to get that ID based on my approach

I got an error when trying nextElementSibling

Sub Test()
    Dim html As New HTMLDocument, post As Object, i As Long
    With CreateObject("MSXML2.XMLHTTP")
        .Open "Get", "C:\Sample.html", False
        .send
        html.body.innerHTML = .responseText
    End With
    Set post = html.querySelectorAll(".list-specification li span")
    For i = 0 To post.Length - 1
        If post.Item(i).innerText = "ID" Then
            MsgBox post.Item(i).nextElementSibling.innerText: Exit For
        End If
    Next i
End Sub
YasserKhalil
  • 9,138
  • 7
  • 36
  • 95

2 Answers2

2

Try doing another NextSibling and then you should find it working:

Set post = Html.querySelectorAll(".list-specification li span")
For j = 0 To post.Length - 1
    If post.Item(j).innerText = "ID" Then
        MsgBox post.Item(j).NextSibling.NextSibling.innerText
        Exit For
    End If
Next j
SIM
  • 21,997
  • 5
  • 37
  • 109
1

The correct property to access I was expecting to be nextElementSibling, but it seems VBA does not implement this.

The NonDocumentTypeChildNode.nextElementSibling read-only property returns the element immediately following the specified one in its parent's children list, or null if the specified element is the last one in the list.

You can however, more correctly, simply take the next index in post i.e. post.item(1). You are collecting both headers and values in the same nodeList so you can use odd/even distinction to separate headers from values.

You can see this if you run the following in console:

post = document.querySelectorAll(".list-specification li span");
var res = ''; for (let [i] of Object.entries(post)) {res += post.item(`${i}`).innerText + ' '};console.log(res);

Spans are inline containers and you can see from html that you have a space between spans which is part of the parent li and this becomes a child text node. This is why your nextSibling hits a text node and errors with the attempt at .innerText accessor. You would want a text node property such as .nodeValue (if you were at the right node).

enter image description here

You can step through, in the console, and see the different properties in action:

enter image description here

As nextElementSibling is not implemented in VBA you would need to chain nextSibling, as per @Sim's answer, if you want to explore nextSibling to solve this particular navigation. However, note that a test of nodeType would avoid throwing an error as you could then apply the appropriate accessor.

QHarr
  • 83,427
  • 12
  • 54
  • 101
  • Thanks a lot my tutor. I will try it. – YasserKhalil Jun 19 '20 at 22:04
  • I recommend the mozilla pages. That is where I go. And use the Console to test things out. – QHarr Jun 19 '20 at 22:05
  • Thanks a lot. I tried what you have written in the console and it works well and as illustrated but this doesn't work in the code. I have added the code so as to test on your side. – YasserKhalil Jun 19 '20 at 22:49
  • 1
    I have edited the answer. That is a good spot. I hadn't realised this wasn't implemented in VBA. That makes @Sim's answer likely a better one for solving your query if you want to use nextSibling rather than index into the collection you have retrieved in post. – QHarr Jun 20 '20 at 00:26