开发者

powershell xml xpath

开发者 https://www.devze.com 2022-12-18 07:30 出处:网络
In Powershell, suppose I have the following xml: <Users> <User Name=\"Foo\"> <Friends> <Friend Name=\"Bar\"/>

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 ge开发者_Python百科t all the users that have a "Bar" as a friend? (In this example it would be Foo,Foo3).

Should I use xpath?

Thanks!


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}


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)


Yes, XPath would be sufficient for that!

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


Whilst the other answers are perfectly acceptable, I personally prefer to do it using SelectNodes.

Given the question XML in a variable $xml, the following will return an array.

$names = $xml.SelectNodes("//User[contains(Friends/Friend/@Name, 'Bar')]/@Name")

The $names variable is an XPathNodeList which is derived from XmlNodeList and will output the following.

#text
-----
Foo
Foo3

If you want to grab the values, you can either iterate or grab by index. For example, $names[1].Value will produce Foo3.

0

精彩评论

暂无评论...
验证码 换一张
取 消