Select Element in XML with Element with certain Attribute(Text)

Viewed 40

I'm currently trying to locate all users in an exported database which are not disabled with PowerShell. I got a XML-file which is structured like this:

<database>
<table name="USERS">
        <entry>
            <cell name="ID">1</cell>
            <cell name="LOGINNAME">admin</cell>
            <cell name="ISDELETED">FALSE</cell>
            <cell name="STATIC">TRUE</cell>
            
        </entry>
        <entry>
            <cell name="ID">2</cell>
            <cell name="LOGINNAME">admin2</cell>
            <cell name="ISDELETED">TRUE</cell>
            <cell name="STATIC">TRUE</cell>
            
        </entry>
        
</table>
</database>

The problem is: The attributes inside are all named "name" and I want to select only the elements where ISDELETED=TRUE.

I tried it with XPath but I don't know how to get the text after I select the with [@name='ID']

[xml]$xml = Get-Content .\db.xml
$xml |Select-Xml "/database/table[@name='USERS']/entry/cell[@name='ID']" | foreach {$_}

Does anyone have an idea? :)

2 Answers

You might just use PowerShell's Xml dot notation and the member-access enumeration feature for this:

$Entry = $Xml.Database.Table.Entry.Where{
    $_.cell.name -eq 'ISDELETED' -and $_.cell.'#text' -eq 'TRUE'
}
$Entry.cell.Where{ $_.name -eq 'LOGINNAME' }.'#text'
admin2

To iterate through all the found entries and e.g. list the cells as a PSCustomObject:

$Entry.ForEach{
    $Properties =[Ordered]@{}
    $_.Cell.ForEach{ $Properties[$_.Name] = $_.'#Text' }
    [PSCustomObject]$Properties
}
ID LOGINNAME ISDELETED
-- --------- ---------
2  admin2    TRUE

Try this to get the correct entries:

/database/table[@name='USERS']/entry[cell[@name='ISDELETED' and text()='FALSE']]

If you want a list of user ID's use this:

/database/table[@name='USERS']/entry[cell[@name='ISDELETED' and text()='FALSE']]/cell[@name='ID']/text()

If you want a list of user names use this:

/database/table[@name='USERS']/entry[cell[@name='ISDELETED' and text()='FALSE']]/cell[@name='LOGINNAME']/text()
Related