Return XML from function

Hi, I’m trying to write a function which return XML variable.

function Create-XML()
{
    [xml]$xml = New-Object System.Xml.XmlDocument
    $Dec = $xml.CreateXmlDeclaration("1.0","UTF-8",$null)
    $xml.AppendChild($Dec)
    $Root = $xml.CreateNode("element","Changes",$null)
    $xml.AppendChild($Root)
    return ,$xml
}

If I’m trying to use output of this as xml type I’m getting error “Cannot convert value “System.Object” to type “System.Xml.XmlDocument””

It’s one of those messy things with powershell and functions.
There is a pretty good explanation in this post (a bit further down):
understanding output

To get around your problem either use [void] or pipe the AppendChild statements to Out-Null.
Otherwise the output of those statements will be added to the output of the function.
Which will give you an array instead of an XML document.

E.g.

function Create-XML()
{
    [xml]$xml = New-Object System.Xml.XmlDocument
    $Dec = $xml.CreateXmlDeclaration("1.0","UTF-8",$null)
    [void]$xml.AppendChild($Dec)
    $Root = $xml.CreateNode("element","Changes",$null)
    [void]$xml.AppendChild($Root)
    return ,$xml
}

From my prior experimentation with methods of discarding output, I’d recommend a slightly different method.

Methods from slowest to fastest:

$Thing | Out-Null # slowest by an order of magnitude
[void] $Thing
$null = $Thing
$Thing > $null # fastest, but only a few ms ahead of the previous

Interesting, at aprox. what amount of statements/iterations did you notice the difference?
Haven’t investigated it myself so I guess I haven’t run into the problem, that I know of at least.

I tested it with some pretty straightforward stuff, at 10,000 iterations:

PS C:\WINDOWS\system32> Measure-Command {1..10000 | % {$_ | Out-Null}}

TotalMilliseconds : 601.827

PS C:\WINDOWS\system32> Measure-Command {1..10000 | % {[void]$_}}

TotalMilliseconds : 91.0079

PS C:\WINDOWS\system32> Measure-Command {1..10000 | % {$null = $_}}

TotalMilliseconds : 92.7215

PS C:\WINDOWS\system32> Measure-Command {1..10000 | % {$_ > $null}}

TotalMilliseconds : 91.0059

So in this particular instance, [void] and > $null worked the same, really. It seems to vary depending on iterations and what kind of things you’re discarding, especially with Out-Null. You’ll also get slightly different results if you repeat the test a few times, and it tends to average roughly in the order I mentioned, although pretty much any alternative to Out-Null works better than it does.

Interestingly, doing this actually works pretty quickly as well:

Out-Null -InputObject $Stuff

So it’s the pipeline that causes the overhead, more than the command. But if you’ve already got a pipeline spun up, I don’t think tacking on Out-Null instead of these other options would really slow things much, in that instance.

When I measure commands like that, I do it a little different to time each execution and average them out. Here are my result. The cmdlet is still slower than the others.

Test Code

"Out-Null pipline"
(1..10000 | % {
    Measure-Command {
        "Test Data" | Out-Null
    }
} | Measure-Object -Average TotalMilliseconds).Average

"Out-Null cmdlet"
(1..10000 | % {
    Measure-Command {
        Out-Null -InputObject "Test Data"
    }
} | Measure-Object -Average TotalMilliseconds).Average

"Void"
(1..10000 | % {
    Measure-Command {
        [void]"Test Data"
    }
} | Measure-Object -Average TotalMilliseconds).Average

'$null='
(1..10000 | % {
    Measure-Command {
       $null = "Test Data"
    }
} | Measure-Object -Average TotalMilliseconds).Average

'Redirect null'
(1..10000 | % {
    Measure-Command {
        "Test Data" > $null
    }
} | Measure-Object -Average TotalMilliseconds).Average

Result 1:

Out-Null pipline
0.26157376
Out-Null cmdlet
0.261141030000001
Void
0.0158285399999992
$null=
0.0159924099999991
Redirect null
0.0187904100000002

Result 2:

Out-Null pipline
0.258285110000001
Out-Null cmdlet
0.25256677
Void
0.0159204299999991
$null=
0.0173433099999992
Redirect null
0.0185149200000002

Result 3:

Out-Null pipline
0.27897332
Out-Null cmdlet
0.264224209999999
Void
0.0176090299999993
$null=
0.0162245199999994
Redirect null
0.0187308600000004

Very interesting! I guess either my prior test or my memory (or both!) was flawed.

I still personally prefer the > $null method syntactically, but it’s nice to know that [void] is on par with $null =, if not better.

$null = Thing doesn’t sit super well with me, it’s a very odd kind of thing there.