20

I am trying to use powershell and XPath to select the name attribute shown in the below xml example.

     $xml_peoples= $file.SelectNodes("//people") 
     foreach ($person in $xml_peoples){
            echo $person.attributes
            #echo $person.attributes.name
     }

Above is the code im running to try and get the name, but it doesn't seem to work. Any suggestions?

<peoples>
    <person name='James'>
        <device>
            <id>james1</id>
            <ip>192.192.192.192</ip>
        </device>
    </person>
</peoples>

Thanks in advance!

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
user1044585
  • 493
  • 2
  • 5
  • 19
  • 2
    Is it a typo? Your xpath has "people" by you have no XML nodes with that name... Is it supposed to be "person" instead? – Andy Arismendi Jul 11 '13 at 01:19
  • 1
    Please specify "doesn't seem to work." What actually happened? I think I know what you expected to happen, but it wouldn't hurt to specify that too. – LarsH Jul 11 '13 at 01:19

4 Answers4

36

These two lines should suffice:

[xml]$xml = Get-Content 'C:\path\to\your.xml'
$xml.selectNodes('//person') | select Name
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • 1
    how can we cast all xml files in a directory as xml objects in Powershell? as in $path = get-childitem -filter *.xml (foreach $file in $path) {...#what goes here} – Sum1sAdmin Mar 02 '17 at 12:57
  • If you have a new question: please post a new question. Don't followup on someone else's question in comments. – Ansgar Wiechers Mar 02 '17 at 13:03
  • sorry, I've posted as a new question http://stackoverflow.com/questions/42561059/powershell-how-to-cast-all-xml-files-as-xml-objects – Sum1sAdmin Mar 02 '17 at 16:43
25

How about one line?

Select-XML -path "pathtoxml" -xpath "//person/@name"

CommonToast
  • 688
  • 12
  • 19
  • 3
    That would be perfect, if it wasn't for Select-XML's atrocious handling of namespaces. You'd need to add a namespace parameter (with a dummy namespace name if it uses the default xmlns like most) for every element in the path. And it's no longer a one-liner (or at least a readable one) if you don't know the namespace value ahead of time. – John Neuhaus Aug 22 '17 at 16:36
16

I'm not sure what $hub is, and you started your code from the middle so it's not clear if you properly set $file to an XmlDocument object, but I think this is what you want:

[System.Xml.XmlDocument]$file = new-object System.Xml.XmlDocument
$file.load(<path to XML file>)
$xml_peoples= $file.SelectNodes("/peoples/person")
foreach ($person in $xml_peoples) {
  echo $person.name
}
Adi Inbar
  • 12,097
  • 13
  • 56
  • 69
7

For anyone that has to work around Select-Xml's garbage namespace handling, here's a one-liner that doesn't care, as long as you know the direct path:

([xml](Get-Content -Path "path\to.xml")).Peoples.Person.Name

The above will return all matching nodes as well. It's not as powerful, but it's clean when you know the schema and want one thing out of it quickly.

John Neuhaus
  • 1,784
  • 20
  • 32