0

I am using this code to load XML that has the potential for errors (human edited).

$xmlReaderSettings = [System.Xml.XmlReaderSettings]::new()
$xmlReaderSettings.CloseInput = $True
$xmlReaderSettings.IgnoreWhitespace = $True
$xmlReaderSettings.IgnoreComments = $True
try {
    $xmlReader = [System.Xml.XmlReader]::Create("$xmlPath\$file", $xmlReaderSettings)
    $tempXml = [System.Xml.XmlDocument]::new()
    $tempXml.Load($xmlReader)
} catch [System.Management.Automation.ItemNotFoundException] {
    Write-PxLog "*_Cannot find '$($file.Name)'"
} catch {
    Write-PxLog "*_Malformed XML in '$($file.Name)'"
    Write-PxLog "*_$($PSItem.Exception.Message)"
    $proceed = $false
} finally {
    $xmlReader.Close()
}

This seems to catch all errors except errors related to comments. Specifically, Autodesk uses arguments like --trigger_point system for their uninstalls, and I have that in the XML. If that XML get's commented there is a problem, because a comment can't contain --. Unfortunately, the code above completely misses that error. I can use

if ($tempXml.DocumentElement) {
    # continue with validating loaded XML
} else {
    # report generic error here
}

I would prefer to provide a more detailed error message, ideally with line numbers. But I would have expected $xmlReaderSettings.IgnoreComments = $True would have solved the issue, as the comments get ignored, and the error is in the comments. If I output the XML again, the comments are missing, but it would seem that IgnoreComments really means IgnoreWellFormedComments, and I have to deal with the issue some other way? Is there a way to actually ignore malformed comments? And if not, why am I not seeing an exception caught? And is there a better answer than "Something happened and it might be a problem in a comment but I can't tell you where, thanks Microsoft." ?

Gordon
  • 6,257
  • 6
  • 36
  • 89
  • 4
    Have you got a (minimal) example of a malformed xml file? – mclayton Jun 01 '22 at 08:27
  • 1
    What exactly does the input look like? `--trigger_point system`? In that case the comment isn't syntactically a comment - thus no errors... – Mathias R. Jessen Jun 01 '22 at 08:30
  • @mathias-r-jessen The XML might look like ``, which is not valid XML, but rather than throwing an exception `XmlReader` just doesn't import anything at all. – Gordon Jun 01 '22 at 10:45
  • If I try your sample with `````` I get the following errors (after replacing ```Write-PxLog``` with ```Write-Host```)... ```*_Malformed XML in ''``` and ```*_Exception calling "Load" with "1" argument(s): "An XML comment cannot contain '--', and '-' cannot be the last character. Line 1, position 12."``` - does the second message not give enough info? – mclayton Jun 01 '22 at 10:51
  • Note also that ```XmlDocument.Load``` will actively read and parse the whole file before it returns, but ```XmlReader``` is passive - you have to "pump" it to read one node at a time from the underlying document by repeatedly calling ```XmlReader.Read``` until you reach the end of the document. Creating a reader and then not calling ```Read``` will not actually read the content of the file - see the ```while``` loop in the sample code at https://learn.microsoft.com/en-us/dotnet/api/system.xml.xmlreader.read?view=net-6.0#examples – mclayton Jun 01 '22 at 11:20
  • @mclayton Intertesting! What version of PowerShell/.NET are you on? I am using PS5.1/.NET 4.8 on Windows 10 21H2, and `$tempXml.Load($xmlReader)` reads the XML fine when there is no error in the comment, but just does nothing when there is an error. No exception, and no loaded document either. – Gordon Jun 01 '22 at 12:43
  • @Gordon - try changing ```Write-PxLog``` to ```write-host```, or remove the entire ```try ... catch``` and just run the 3 lines inside the ```try``` block - you might be swallowing the error message in your logger. – mclayton Jun 01 '22 at 12:47

0 Answers0