Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

powershell xml xpath

In Powershell, suppose I have the following xml:

  <Users>
    <User Name="Foo">
      <Friends>
        <Friend Name="Bar"/>
      </Friends>
    </User>
    <User Name="Foo2" />
    <User Name="Foo3">
      <Friends>
        <Friend Name="Bar"/>
      </Friends>
    </User>
  </Users>

How can I get all the users that have a "Bar" as a friend? (In this example it would be Foo,Foo3).

Should I use xpath?

Thanks!

like image 928
Yuval Peled Avatar asked Jan 29 '10 20:01

Yuval Peled


3 Answers

I have a preference for using XPath these days. I've run into issues using PowerShell's xml adapter that are annoying like the name collision on item:

$xml = [xml]@'
  <Users> 
    <User Name="Foo"> 
      <Friends> 
        <Friend Name="Bar"/> 
      </Friends> 
    </User> 
    <User Name="Foo2" /> 
    <User Name="Foo3"> 
      <Friends> 
        <Friend Name="Bar"/> 
      </Friends> 
    </User> 
  </Users> 
'@

Select-Xml '//User[contains(Friends/Friend/@Name, "Bar")]' $xml |%{$_.Node.Name}
like image 156
Keith Hill Avatar answered Sep 20 '22 00:09

Keith Hill


In this case I would use XPath as well. @TomWij provided the correct xpath.

In case that the xpath expression would be too complicated, I would for sure used the 'classic' approach.

$x.Users.User | ? { $_.Friends.Friend.Name -eq 'Bar' }

(in this case if you don't have script mode on, it doesn't matter that there is no Friends element. $_.Friends will return $null and $null.Friend returns $null as well and so on. So finally $null -eq 'Bar' returns false and the element is removed by Where-Object)

like image 41
stej Avatar answered Sep 20 '22 00:09

stej


Yes, XPath would be sufficient for that!

Check Powershell to test your XPath to see how it can be done.

like image 26
Tamara Wijsman Avatar answered Sep 21 '22 00:09

Tamara Wijsman