Peyre
Peyre

Reputation: 573

powershell, xml, how to differentiate and element

is it possible to differentiate the origin of a value in XML data (attribute or element) once the data has been read? if I run the following script

$xml= [xml]@'
<?xml version="1.0" encoding="utf-8"?>
<root>
    <item id="001">
    </item>
    <item>
        <id>002</id>
    </item>
    <item id="003">
        <id>003 bis</id>
    </item>
</root>
'@

$items = Select-Xml -Xml $xml -XPath '//item'
$items | %{ $_.node }

I get the same structure in $_.node for id for the two first items and an array of values for id for the last one

id
--
001
002
{003, 003 bis}

Upvotes: 2

Views: 170

Answers (1)

mklement0
mklement0

Reputation: 439287

PowerShell's adaptation of the XML DOM represents both attributes and child elements as if they were properties of an XML element.

However, non-leaf XML elements (those that have attributes and/or child nodes that are elements) retain their System.Xml.XmlElement identity, and are simply decorated with the properties representing attributes and child elements, using PowerShell's ETS (Extended Type System).

Therefore, you also have access to an XmlElement's native type members (properties and methods), which allows you to distinguish between attributes and child elements:

$xml= [xml] @'
<?xml version="1.0" encoding="utf-8"?>
<root>
    <item id="001">
    </item>
    <item>
        <id>002</id>
    </item>
    <item id="003">
        <id>003 bis</id>
    </item>
</root>
'@

Select-Xml -Xml $xml -XPath '//item' | ForEach-Object {
  [pscustomobject] @{
    IdAttribute = $_.Node.GetAttribute('id')   # get attribute
    IdChildElement = $_.Node['id'].InnerText   # get child element 
  }
}

The above yields:

IdAttribute IdChildElement
----------- --------------
001         
            002
003         003 bis

Upvotes: 3

Related Questions