SelectSingleNode vs dot reference

142 Views Asked by At

I was under the impression that dot referencing an XML node was the same as SelectSingle node, but there seems to be a difference. Given

$xml = [Xml]@"
<Root> 
    <Empty>
    </Empty>
    <Filled>
        <Contents>STRING</Contents>
        <Contents2>STRING2</Contents2>
    </Filled>
</Root>
"@

($xml.DocumentElement.Filled).GetType().FullName
($xml.SelectSingleNode('/Root/Filled')).GetType().FullName

both return a type of [System.Xml.XmlElement]. However

($xml.DocumentElement.Empty).GetType().FullName
($xml.SelectSingleNode('/Root/Empty')).GetType().FullName

returns [System.String] and [System.Xml.XmlElement].

This came up as I was attempting to import an element in to an empty Element vs a filled Element. Given

$newXml = [Xml]@"
<Contents3>STRING3</Contents3>
"@

$newElement = $xml.ImportNode($newXml.get_DocumentElement(), $true)
$xml.DocumentElement.Filled.AppendChild($newElement)

will import the new element, while

$newElement = $xml.ImportNode($newXml.get_DocumentElement(), $true)
$xml.DocumentElement.Empty.AppendChild($newElement)

will fail with Method invocation failed because [System.String] does not contain a method named 'AppendChild'. This makes it seem like the dot reference is referencing the contents of the element, not the element itself. At least when the element is empty. But when the element contains other elements, it seems like the dot notation references the actual element, since multiple contained elements isn't treated any differently from a single contained element. On the other hand,

$xml.SelectSingleNode('/Root/Empty')

and

$xml.SelectSingleNode('/Root/Filled')

are definitely both referencing the Element itself, and both work for AppendChild.

Am I correct in this understanding, that dot referencing sometimes references the actual element and sometimes the contents? And, is there a way to use dot reference to AppendChild to an empty Element, or is it just best to always use SelectSingleNode?

I feel like dot referencing is safe for passing elements to other functions, but actually changing anything requires using XPath, but I want to be sure I am correct in that, and maybe someone can explain WHY dot referencing seems to behave differently?

0

There are 0 best solutions below