How to read only first leaf of xml attribute

Viewed 38

I have Powershell code like this:

$Xml = @"
<?xml version="1.0" encoding="utf-8"?>
<DisplayDefinitionTable>
    <columns>
        <column_entry order_num="0" relation_to_base="Item.current_name">current_name</column_entry>
    </columns>
    <rows>
        <row>
            <object_tag tag="91859" uid="TdjJhBMdpQNFhC"/>
            <object_tag tag="86504" uid="TtvJBp53pQNFhC"/>
            <row_element column="0" component_tag="91859" property_name="current_name">EAUX</row_element>
        </row>
        <row>
            <object_tag tag="92069" uid="DCuJhBMdpQNFhC"/>
            <object_tag tag="86504" uid="TtvJBp53pQNFhC"/>
            <row_element column="0" component_tag="92069" property_name="current_name">VISS</row_element>
        </row>
    </rows>
</DisplayDefinitionTable>

"@

Select-Xml -Content $Xml -XPath "//object_tag" | foreach {$_.node.uid}

And results:

Select-Xml -Content $Xml -XPath "//object_tag" | foreach {$_.node.uid}


TdjJhBMdpQNFhC
TtvJBp53pQNFhC
DCuJhBMdpQNFhC
TtvJBp53pQNFhC

PS C:\Windows\system32> 

The main goal is to take only first uid value of every leaf in the file so proper answer should looks like this:

TdjJhBMdpQNFhC
DCuJhBMdpQNFhC


PS C:\Windows\system32> 

How to do this?? Thanks

2 Answers

Try specifying your command as:

Select-Xml -Content $Xml -XPath "//object_tag[1]" | foreach {$_.node.uid}

Note, the addition of the [1] to the XPath to specifically pull just the first instance.

Or you also could have your command like the below to save piping to the foreach:

(Select-Xml -Content $Xml -XPath "//object_tag[1]").node.uid

Both variations above give you the results you're looking for.

Also, this great cheat sheet on XPath has some further information on indexing, etc...

It is probably easier use the (accelerated) standard .Net xml parser this will also better target the specific row/object_tag uids and not all other possible uid at other levels:

$Xml = [xml]@'
<?xml version="1.0" encoding="utf-8"?>
<DisplayDefinitionTable>
    <columns>
        <column_entry order_num="0" relation_to_base="Item.current_name">current_name</column_entry>
    </columns>
    <rows>
        <row>
            <object_tag tag="91859" uid="TdjJhBMdpQNFhC"/>
            <object_tag tag="86504" uid="TtvJBp53pQNFhC"/>
            <row_element column="0" component_tag="91859" property_name="current_name">EAUX</row_element>
        </row>
        <row>
            <object_tag tag="92069" uid="DCuJhBMdpQNFhC"/>
            <object_tag tag="86504" uid="TtvJBp53pQNFhC"/>
            <row_element column="0" component_tag="92069" property_name="current_name">VISS</row_element>
        </row>
    </rows>
</DisplayDefinitionTable>
'@

and the PowerShell Xml dot notation syntax:

$xml.DisplayDefinitionTable.Rows.Row.ForEach{ $_.object_tag[0].uid }
TdjJhBMdpQNFhC
DCuJhBMdpQNFhC
Related