2

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}
2
  • Which one are you interested in? Commented Feb 15, 2021 at 19:45
  • @MathiasR.Jessen one or the other. or both. I know I can modify the XPath filter to select only the attributes, or only the elements, but my question is: once loaded without any special filter, can I sort out the one coming from the attributes and the one coming from elements. Commented Feb 15, 2021 at 21:35

1 Answer 1

3

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
Sign up to request clarification or add additional context in comments.

1 Comment

I had to play a bit with it to make it work in strict mode but it's what I was looking for

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.