I'm executing an HTTP Get request (via Invoke-WebRequest
) against a website, that's in turn, is returning the following XML structure:
<?xml version="1.0" encoding="utf-8"?>
<ROOT xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<VENDOR>
<SUBJECT>Check Oil</SUBJECT>
<VENDORID>NA</VENDORID>
<VANTIVE>2</VANTIVE>
<MODEL>I</MODEL>
<DESCRIPTION>Success</DESCRIPTION>
</VENDOR>
<VENDOR>
<SUBJECT>Check Lights</SUBJECT>
<SIGN>N</SIGN>
<VENDORID>NA</VENDORID>
<VANTIVE>2</VANTIVE>
<MODEL>I</MODEL>
<DESCRIPTION>Success</DESCRIPTION>
</VENDOR>
<VENDOR>
<SUBJECT>Check Engine</SUBJECT>
<SIGN>N</SIGN>
<VENDORID>NA</VENDORID>
<VANTIVE>2</VANTIVE>
<MODEL>I</MODEL>
<DESCRIPTION>Success</DESCRIPTION>
</VENDOR>
</ROOT>
When trying to parse the XML data, using the ConvertTo-Xml
cmdlet:
$result = Invoke-WebRequest -Uri 'https://mycars.com/list/cars' -UseBasicParsing -Method Get
$resultinxml = $result.Content | ConvertTo-Xml
$resultinxml.Objects.Object.'#text'
Everything is working properly.
But when I'm trying to use the [xml] accelerator type instead:
$result = Invoke-WebRequest -Uri 'https://mycars.com/list/cars' -UseBasicParsing -Method Get
[xml] $resultinxml = $result.Content
The following error is occurred:
Cannot convert value "<?xml version="1.0" encoding="utf-8"?>
<ROOT xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<VENDOR>
<SUBJECT>Check Oil</SUBJECT>
<VENDORID>NA</VENDORID>
<VANTIVE>2</VANTIVE>
<MODEL>I</MODEL>
<DESCRIPTION>Success</DESCRIPTION>
</VENDOR>
<VENDOR>
<SUBJECT>Check Lights</SUBJECT>
<SIGN>N</SIGN>
<VENDORID>NA</VENDORID>
<VANTIVE>2</VANTIVE>
<MODEL>I</MODEL>
<DESCRIPTION>Success</DESCRIPTION>
</VENDOR>
<VENDOR>
<SUBJECT>Check Engine</SUBJECT>
<SIGN>N</SIGN>
<VENDORID>NA</VENDORID>
<VANTIVE>2</VANTIVE>
<MODEL>I</MODEL>
<DESCRIPTION>Success</DESCRIPTION>
</VENDOR>
</ROOT>
" 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."
At line:1 char:1
+ $webreqcontent = [xml] ($result.Content)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastToXmlDocument
Which is very odd, as the XML structure hasn't been changed and is XML valid.
Do accelerator types in PowerShell has some prerequisites or limitations, that could cause this issue?
Building on the helpful comments on the question:
When trying to parse the XML data, using the ConvertTo-Xml cmdlet:
ConvertTo-Xml
does not parse XML, it creates XML representations (serialization) of arbitrary .NET instances - and since the resulting XML format is neither documented nor is there a complementary cmdlet to interpret (deserialize) it, this cmdlet is virtually useless - see GitHub issue #8311.
GitHub issue #3898 is a green-lit proposal to introduce ConvertTo-CliXml
and ConvertFrom-CliXml
cmdlets, instead, which will use the standardized CLIXML format that PowerShell uses for cross-process serialization, such as in remoting.
In other words: your use of ConvertTo-Xml
won't work as intended.
If you use Invoke-RestMethod
instead of Invoke-WebRequest
, XML parsing is built in (with web services that return XML) and directly returns a [xml]
(System.Xml.XmlDocument
) instance.
# If the web-service call returns XML, Invoke-RestMethod automatically
# parses it into a [xml] instance.
$resultXml = Invoke-RestMethod -Uri 'https://mycars.com/list/cars'
However, your error message suggests that you have one or more extraneous characters preceding the XML text - even though, curiously, that isn't reflected in the error message, at least as shown in your question.
[xml] '!<foo/>'
Conceivably, the XML text is preceded by a BOM (byte order mark), even though it normally shouldn't in this context.
$result = Invoke-WebRequest -Uri 'https://mycars.com/list/cars' -UseBasicParsing
# Skip the BOM character .
[xml] $resultinxml = $result.Content.Substring(1)
A solution to a related problem - an XML response getting misinterpreted due to a character-encoding mismatch - can be found in this answer.