New-Object without variable

Why does creating an object in a variable first and then using the LoadXml work, but not all at the same time?

$xml=@"
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
    HELLo
</Task>
"@

#Works
$xmlObject=New-Object -TypeName "System.Xml.XmlDocument"
$xmlObject.LoadXml($xml)

#Does not work
$xmlObjectNow=(New-Object -TypeName "System.Xml.XmlDocument").LoadXml($xml)

The LoadXML() method doesn’t return anything (it’s declared as void) so there’s nothing to assign to the $xmlObjectNow variable.

Compare this to the CreateDocumentFragment() method which returns an object of type XmlDocumentFragment and populates the variable with the returned object:

PS E:\Temp> $xmlObject | Get-Member -MemberType Method -Name LoadXml

   TypeName: System.Xml.XmlDocument

Name    MemberType Definition
----    ---------- ----------
LoadXml Method     void LoadXml(string xml)
PS E:\Temp> $xmlObject | Get-Member -MemberType Method -Name CreateDocumentFragment

   TypeName: System.Xml.XmlDocument

Name                   MemberType Definition
----                   ---------- ----------
CreateDocumentFragment Method     System.Xml.XmlDocumentFragment CreateDocumentFragment()
E:\Temp> $xmlDoc = (New-Object -TypeName "System.Xml.XmlDocument").CreateDocumentFragment()
PS E:\Temp> $xmlDoc | Get-Member

   TypeName: System.Xml.XmlDocumentFragment
1 Like

This still doesn’t help me understand why the first example works and the second one does not. In this example, it still shows a return of void, but an object is created:

$xml=@"
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
    HELLo
</Task>
"@

$xmlObject=New-Object -TypeName "System.Xml.XmlDocument"

$xmlObject| Get-Member -MemberType Method -Name LoadXml
$xmlObject.LoadXml($xml)
$xmlObject
$xmlObject| Get-Member -MemberType Method -Name LoadXml

I think the part that @matt-bloomfield said that you’re missing is that the method of an XmlDocument for loading XML does not return an object.
If you call that method, there is no output, therefore there is nothing for your variable to capture.
When you create an object and immediately call that method, it essentially spawns and disappears. e.g.

#Does not work
$xmlObjectNow=(New-Object -TypeName "System.Xml.XmlDocument").LoadXml($xml)

Another syntax for accomplishing the same thing:

[System.Xml.XmlDocument]::new().LoadXml($xml)

You have to first instantiate the object using the new() constructor, then you can call the LoadXml method of that object.
Go ahead and run my last line of code by itself (assuming $xml is defined) and see that nothing comes out. This is why your variable is empty.

Based on the constructors that are available you’re going to have to create the object first, and then load the xml.

1 Like

Why not just try

Blockquote

$xml=@"
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
    HELLo
</Task>
"@

try {
  $objXml = [xml]$xml
} catch {
  write-host "xml conversion error : $($_.exception.message)
}

The result is an object with TypeName System.Xml.XmlDocument

1 Like