How to check if two references are pointing to the same XmlNode object?

All elements belonging to an XmlDocument have a new object returned when queried - you can see it in the debugger.

In the debugger on a BREAK statement view an XmlDocument. Look a the address of for example FirstChild, then in the Variables popup menu re-choose the same XmlDocument and you will see that FirstChild is a new object (has a new memory address).

You could use Parent to climb back out of the hierarchy and form a unique path to the node. At each level, follow PreviousSibling to get a count of which child the node is of the parent.

Given your example xml of

The path to the second “c” node might look like

a/c:3

Just checked … 2007r4 is this way (which predates my arrival here)
I suspect there’s a certain amount of simplicity in the plugin implementation to return a new object every time.
This way you don’t have to keep a list of references to things you’ve already returned to make it so you can return the same one if its asked for over & over.

[quote=123252:@Norman Palardy]The trick here is that the XML.FirstChild.Child(0) returns a new object that refers to the same underlying data
So while they refer to the same data they are NOT the same reference

However IF you do

n1 = xdoc.FirstChild.Child(0) n2 = n1

now N1 and N2 definitely ARe two references to the same XML elements[/quote]

Thanks for clarifying Norman. With this new knowledge I can easily ensure during future use of the class to create references like you show in your example, instead of using Child(0) each time.

I guess there was good reasons for implementing the code the way it is implemented, but also do agree with Massimo that Child() should return the same object each time. Especially because of the XmlNode.RemoveChild(node As Xml) method.

The design decision that references are used instead of indexes with RemoveChild, implies that a programmer should be able to rely on the references.

Since it has always been this way for a long time, it obviously is not something that affects many (if any) developers anyway.

Tim has given an elegant workaround to the solution, so my problem is solved :slight_smile:

[quote=123396:@Norman Palardy]Just checked … 2007r4 is this way (which predates my arrival here)
I suspect there’s a certain amount of simplicity in the plugin implementation to return a new object every time.
This way you don’t have to keep a list of references to things you’ve already returned to make it so you can return the same one if its asked for over & over.[/quote]

While this is probably here from years, if not from the start, I still feel this is bad.
Ok, there are workarounds, but the fact is the framework MUST be consistent on things like this, because it’s the foundation upon everything is built. A developer must trust the framework is providing unique objects if not explicitly said with a Clone method. And Clone is normally an alternative, not the default.

You can solve the issue reporting in the docs this weird behavior, but still it’s a poor implementation. Really these are the things which makes you lose hours in finding bugs.

What really scare me, is this behavior can be present in other parts of the framework.

The XML plugin was not originally written by Xojo / Real.
So I have no idea why it is / was written this way.
Just saying that it is this way.

At some point we really need to replace the plugin with an implementation based on something like Xerces
See <https://xojo.com/issue/18>

I ran into this issue again today, where I need to get the index of an XMLNode in it’s parent’s child array…

Here is a extended method that now returns this index value should anyone need to do the same:

[code]Function Index(extends node As XmlNode) As Integer
Dim result As Integer
Dim n As XmlNode

n = node

result = -1
do
result = result + 1
n = n.PreviousSibling
loop until n = nil

return result
End Function
[/code]

So, if you want to get a node’s index value in its parent’s Child array, you can simply call the method like:

someValue = myNode.Index

in my plugin I make a lot of work in some cases (e.g. cocoa objects) to make sure the same pointer in C gives the same Wrapper object.
But this is not required.
XMLNode class may not support it.

[quote=213371:@Christian Schmitz]in my plugin I make a lot of work in some cases (e.g. cocoa objects) to make sure the same pointer in C gives the same Wrapper object.
But this is not required.
XMLNode class may not support it.[/quote]

In fact XMLNode seems not supporting this.
But while this may be not required, is very advisable to behave in such way.
At least for framework consistency.