1

I want to convert retrieve the info in xml tags using powershell. But this error message is what I am facing:

Select-Xml : Cannot convert value "System.Xml.XmlDocument" to type "System.Xml.XmlDocument". Error: "The specified node cannot be inserted as the valid child of this node, because the specified node is the wrong type."

[xml]$xml=
@"
<BESAPI xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:noNamespaceSchemaLocation="BESAPI.xsd">
<Computer Resource="https://dsw11.lab.g:52311/api/computer/549"/>
<Computer Resource="https://dsw11.lab.g:52311/api/computer/550"/>
<Computer Resource="https://dsw11.lab.g:52311/api/computer/552"/>
<Computer Resource="https://dsw11.lab.g:52311/api/computer/551"/>
</BESAPI> 
"@


#I have tried these alternatives for result, but both of them are not working

#$result = Select-Xml -Content $xml -XPath "//Computer Resource" | foreach {$_.node.InnerXML}
$result = Select-Xml -Content $xml -XPath "//Computer Resource" | foreach {[pscustomobject]@($_.node.InnerXML)}

I want to retrieve the ID's from the computer resource. for that again,

foreach($str in $result)
{
$res = $str.split('/')[-1]
# next steps
}

I have searched a lot but not a thing is working.

Thanks for your help in advance.

3
  • First of all, since you're passing an XML document, you need -Xml instead of -Content. Second, the nodes are actually attributes of an element, not nodes named "Computer Resource", so the XPath would be //Computer/@Resource. And last but not least, using Select-Xml for this is unnecessarily complex, since you can just use the properties PowerShell magics up for XML documents and collections: $xml.BESAPI.Computer.Resource Commented May 7, 2020 at 12:01
  • [xml]$xml = @" <BESAPI xmlns:xsi="w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BESAPI.xsd"> <Computer Resource="dsw12tem01.cgdevlab.cg:52311/api/computer/5379"> <Property Name="Computer Name">DSW102</Property> </Computer> </BESAPI> in this case, i want to retrieve computer name 'DSW12SL02'. how can that be done? Commented May 7, 2020 at 13:37
  • Well it can't, since DSW12SL02 occurs nowhere in that document. You could ask a new question if necessary. Commented May 7, 2020 at 13:41

2 Answers 2

3
Select-Xml -xml $xml -XPath "//Computer" | 
  foreach { $_.node.Resource.split('/')[-1] }

549
550
552
551
Sign up to request clarification or add additional context in comments.

Comments

0

Go through each Resource attribute and extract the leaf item from the URL with Split-Path:

foreach ($url in $xml.BESAPI.Computer.Resource) {
    Split-Path -Path $url -Leaf
}

Or using Foreach-Object if you prefer using pipelines instead of foreach enumeration:

$xml.BESAPI.Computer.Resource | ForEach-Object {
    Split-Path -Path $_ -Leaf
}

Output:

549
550
552
551

From the documentation for -Leaf:

Indicates that this cmdlet returns only the last item or container in the path. For example, in the path C:\Test\Logs\Pass1.log, it returns only Pass1.log.


Update

As @Jeroen Mostert mentioned in the comments, full URLs are not paths, so Split-Path -Leaf may run into issues.

A safer solution would be to convert the URL to a System.Uri object, then use the System.Uri.LocalPath property instead:

foreach ($url in $xml.BESAPI.Computer.Resource) {
    Split-Path -Path ([uri]$url).LocalPath -Leaf
}

Or just use split, similar to js2010's answer:

foreach ($url in $xml.BESAPI.Computer.Resource) {
    ($url -split "/")[-1]
}

1 Comment

Full URLs are not paths, however. When passed through Split-Path with -Leaf you have a decent chance of things working, but it's still iffy. A simple string split seems more appropriate; if you must use Split-Path it'd be safer to work on ([uri] $url).LocalPath instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.