2010-01-29 22 views
8

En Powershell, supongamos que tengo el siguiente código XML:PowerShell XPath XML

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

¿Cómo puedo obtener todos los usuarios que tienen un "bar" como amigo? (en este ejemplo sería Foo, Foo3).

¿Debo usar xpath?

Gracias!

Respuesta

12

Tengo una preferencia para usar XPath en estos días. Me he encontrado con problemas al utilizar el adaptador de XML PowerShell que son molestas como el nombre de colisión en 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} 
1

Sí, ¡XPath sería suficiente para eso!

Compruebe Powershell to test your XPath para ver cómo se puede hacer.

+0

/Users/User[contains(./Friends/Friend/@Name, "bar")] –

+1

Sírvanse proporcionar mejor enlace. Este artículo no usa el nuevo cmdlet 'Select-Xml' de V2. Es mucho más útil: 'Select-Xml -xml $ xml -xpath '/Users/User[contains(./Friends/Friend/@Name," Bar ")]' | select -exp node' – stej

+0

No puedo editar más mi comentario, así que aquí hay un enlace a la publicación de Jaykul: http://huddledmasses.org/xpath-and-namespaces-in-powershell/ – stej

3

En este caso también usaría XPath. @TomWij proporcionó el xpath correcto.

En caso de que la expresión xpath sea demasiado complicada, seguramente usaría el enfoque 'clásico'.

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

(en este caso si usted no tiene el modo de secuencia de comandos en, no importa que no hay ningún elemento Friends. $_.Friends regresará $null y $null.Friend vuelve $null así y así sucesivamente. Así que finalmente $null -eq 'Bar' devuelve falso y el elemento es eliminado por Where-Object)