Reputation: 987
<department>
<employee name="ABC">
<salary value="basic">5000</salary>
<salary value="allowance">8000</salary>
</employee>
<employee name="XYZ">
<salary value="basic">6000</salary>
<salary value="allowance">3000</salary>
</employee>
</department>
How to get the employee names whose allowance is greater than basic in powershell.
I have tried below but does not give me the result
$result= $xml |Select-Xml '//department'|
ForEach{
$basic=$_.Node.employee.salary.value | where {$_.Node.employee.salary.value -eq 'basic'}
$allowance=$_.Node.employee.salary.value | where {$_.Node.employee.salary.value -eq 'allowance'}
if ($allowance -ge $basic)
{
$name=$_.Node.employee.name
}
}
echo $result
Upvotes: 1
Views: 125
Reputation: 25021
If you want to use Select-Xml
, you can do the following:
$node = $xml | Select-Xml -XPath "//department/employee[./salary[@value='basic'] < ./salary[@value='allowance']]"
$node.node.name # Output the employee name
See XPath Examples for xpath expression examples. See Boolean, Comparison, and Set Expressions for more information on XPath operators including the escaping of <
and >
where necessary.
Upvotes: 4
Reputation: 27516
In your example, $_.Node.employee.salary.value is just an array of strings, so the where cmd can't reference any properties, and $basic and $allowance end up being blank. Also, the foreach only loops one time, because there's only one department.
This way, you're already piping in an array of employees, instead of the one department. I also get the node property out of the way. $basic and $allowance are still objects with value and #text properties. I output the employee object that matches. It's sort of like what you were trying to do. The comparison has to be [int], or else '500' is greater than '4000'.
(Select-Xml /department/employee salary.xml).node |
ForEach {
$basic = $_.salary | where value -eq basic
$allowance = $_.salary | where value -eq allowance
if([int]$allowance.'#text' -ge $basic.'#text') {
$_ | select name,
@{n='basic'; e={$basic.'#text'}},
@{n='allowance'; e={$allowance.'#text'}}
}
}
name basic allowance
---- ----- ---------
ABC 5000 8000
Upvotes: 0
Reputation: 23763
I would use the PowerShell XML parser ([XML]
) to create a XMLDocument:
$xml = [XML]'
<department>
<employee name="ABC">
<salary value="basic">5000</salary>
<salary value="allowance">8000</salary>
</employee>
<employee name="XYZ">
<salary value="basic">6000</salary>
<salary value="allowance">3000</salary>
</employee>
</department>'
Then it is as simple as:
$xml.Department.Employee | % {
$allowance = [Int]($_.salary | ? {$_.value -eq 'allowance'}).'#text'
$basic = [Int]($_.salary | ? {$_.value -eq 'basic'}).'#text'
If ($allowance -ge $basic) {$Name = $_.name}
}
Upvotes: 0