2010-01-29 11 views
8

In Powershell, nehme ich folgende xml haben:Power xml xpath

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

Wie kann ich alle Benutzer erhalten, die eine „Bar“ als Freund haben? (In diesem Beispiel wäre es Foo, Foo3).

Sollte ich Xpath verwenden?

Danke!

Antwort

12

Ich habe eine Präferenz für die Verwendung von XPath in diesen Tagen. Ich habe Probleme laufen in Powershell XML-Adapter verwenden, die auf item wie der Name Kollision ärgerlich sind:

$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

Ja, XPath wäre dafür ausreichend!

Überprüfen Sie Powershell to test your XPath, um zu sehen, wie es gemacht werden kann.

+0

/Users/User[contains(./Friends/Friend/@Name, „Bar“)] –

+1

Bitte geben bessere Verbindung. Dieser Artikel verwendet nicht das neue Cmdlet 'Select-Xml' aus V2. Es ist viel praktischer: 'Select-Xml -xml $ xml -xpath '/Users/User[contains(./Friends/Friend/@Name," Bar ")]' | wähle -exp node' – stej

+0

Ich kann meinen Kommentar nicht mehr bearbeiten, also hier ist ein Link zu Jaykul's Beitrag: http://huddledmasses.org/xpath-and-namespaces-in-powershell/ – stej

3

In diesem Fall würde ich auch XPath verwenden. @TomWij hat den korrekten XPath bereitgestellt.

Falls der Xpath-Ausdruck zu kompliziert wäre, würde ich sicher den "klassischen" Ansatz verwenden.

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

(in diesem Fall, wenn Sie Skript-Modus haben nicht auf, es spielt keine Rolle, dass es keine Friends Element. $_.Friends kehrt $null und $null.Friend kehrt $null auch und so weiter. So endlich $null -eq 'Bar' gibt false zurück und das Element wird von Where-Object entfernt)