System.XML.XPath.XPathDocument
(1)
System.Xml.XmlDocument
(1)
Console.WriteLine
(1)
SelectSingleNode
(1)
XmlDocument
(1)
XmlElements
(1)
InnerText
(1)
XmlNodes
(1)

XmlDocument SelectSingleNode doesn't work

Asked By John Shwon
16-Nov-07 01:12 AM
I'm trying to parse the XML snippet below using PowerShell.


The C# code below works perfectly and prints "Hello World" as expected.

XmlDocument doc = new XmlDocument();
doc.Load(@"C:\test.xml");
string str = doc.SelectSingleNode("//Body").InnerText;
Console.WriteLine(str);

Trying the following in PowerShell doesn't seem to work:

$doc = new-object "System.Xml.XmlDocument"
$doc.Load("c:\test.xml")
$doc.SelectSingleNode("//Body").InnerText;

Where am I going wrong?

XmlDocument SelectSingleNode doesn't work

Asked By Shay Levi
17-Nov-07 03:20 PM
You can get the node text by:

PS > $doc = new-object "System.Xml.XmlDocument"
PS > $doc.Load("c:\test.xml")
PS > $doc.Envelope.Body.InnerText;
hello world



If you have multiple body elements:

PS > $xml=[xml]"<Envelope>hello worldhello world1</Envelope>"
PS > $xml.Envelope.Body
hello world
hello world1

PS > $xml.Envelope.Body.Count
2

PS > $xml.Envelope.Body[0]
hello world

PS > $xml.Envelope.Body[1]
hello world1


As for the SelectSingleNode member (altough it is visible to $xml), not sure,
I think you need to use XPath ([System.XML.XPath.XPathDocument])

HTH

-----
Shay Levi
$cript Fanatic
http://scriptolog.blogspot.com

Xmldocument is a type that Powershell adapts.

Asked By Karl Prosser[MVP]
16-Nov-07 02:32 AM
Xmldocument is a type that Powershell adapts. so it can do some special
things on it.. for my example i'll use your same document but i won't
load it from file i will create it with a typecast but it should work
the same

$doc = [xml]'<Envelope>hello world</Envelope>'

if you do $doc.gettype()you'll notice its still a system.xml.Xmldocument

however some of the properties of that class are hidden from powershell
are some more added. Notably if you do
$doc | get-member you'll see an Envelope. Powershell actually adapts the
contents of hte xml document as properties so you can simply do..

$doc.envelope

or even

$doc.envelope.body

which will return the XmlNodes XmlElements etc.

however what if you happened to have an xml node called innertext, you'd
have a conflict, thus powershell hides a bunch of the build in properties

if you run
$doc.SelectSingleNode("//Body")

you'll notice you actually get results in your console. its just you
can't access the innertext.. well with adapted types in powershell you
can always get the underlying dotnet objects properties and methods with
.psbase

$doc.SelectSingleNode("//Body").psbase.innertext

will do the job
but also you could do
$doc.SelectSingleNode("//Body").get_Innertext()

or a property powershell adds #text

$doc.SelectSingleNode("//Body")."#text"

Hope this helps.
Post Question To EggHeadCafe