Parsing XML File – Powershell
I need to read a value from a specific node (one of the first nodes of the xml file) in the xml file, but when I open the xml file using this method:
$xml = [xml](Get-Content $file)
… when there is an unclosed tag (even after my node), I get this type of error:
Cannot convert value "System.Object []" to type "System.Xml.XmlDocument". Error: "The 'DatiRie Summary' start tag on line 83 position 5 does not match the end tag of 'DatiBeniServizi'. Line 84, position 5. ".
Now, I want to suppress this type of error and always read my value inside my tag even if there are unclosed tags in the xml file (before or after the node that is necessary for me). I hope I have been clear and I apologize for disturbing you.
Thanks so much, Andrew
When you use the XML type helper (i.e. [xml] ...
) it validates the xml to make sure it’s well-formed before you can access the contents, but from the error message it looks like you’ve got some mismatching tags- e.g:
$text = @( "<DatiRie_Summary>", " <node>text</node>", "</DatiBeniServizi>" ) $xml = [xml] $text
which outputs
Cannot convert value "System.Object[]" to type "System.Xml.XmlDocument". Error: "The 'DatiRie_Summary' start tag on line 1 position 2 does not match the end tag of 'DatiBeniServizi'. Line 3, position 3." At line:1 char:1 + $xml = [xml] $text + ~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [], RuntimeException + FullyQualifiedErrorId : InvalidCastToXmlDocument
The best way to resolve this is to fix your xml file, but if you don’t control the generation of the file then that might not be possible.
A poor second option might be to use the XmlReader class instead. That validates the xml "just in time" and lets you read up to the first malformed element. However, it’s a lot more work to use, so the trade-off might not be worth it, and you still hit the same exception in the end anyway…
$text = @" <DatiRie_Summary> <node>mytext</node> </DatiBeniServizi> "@ $xmlReader = [System.Xml.XmlReader]::Create((new-object System.IO.StringReader($xmlText))); while( $xmlReader.Read() ) { write-host ($xmlReader.NodeType.ToString() + ": '" + $xmlReader.Name + "' = '" + $xmlReader.Value + "'") }
outputs
Element: 'DatiRie_Summary' = '' Whitespace: '' = ' ' Element: 'node' = '' Text: '' = 'text' EndElement: 'node' = '' Whitespace: '' = ' ' Exception calling "Read" with "0" argument(s): "The 'DatiRie_Summary' start tag on line 1 position 2 does not match the end tag of 'DatiBeniServizi'. Line 3, position 3." At line:1 char:8 + while( $xmlReader.Read() ) + ~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : XmlException