1

I'm using the code found here to perform XML validation:

function Test-Xml {
[cmdletbinding()]
param(
    [parameter(mandatory=$true)]$InputFile,
    $Namespace = $null,
    [parameter(mandatory=$true)]$SchemaFile
)

BEGIN {
    $failCount = 0
    $failureMessages = ""
    $fileName = ""
}

PROCESS {
    if ($inputfile)
    {
        write-verbose "input file: $inputfile"
        write-verbose "schemafile: $SchemaFile"
        $fileName = (resolve-path $inputfile).path
        if (-not (test-path $SchemaFile)) {throw "schemafile not found $schemafile"}
        $readerSettings = New-Object -TypeName System.Xml.XmlReaderSettings
        $readerSettings.ValidationType = [System.Xml.ValidationType]::Schema
        $readerSettings.ValidationFlags = [System.Xml.Schema.XmlSchemaValidationFlags]::ProcessIdentityConstraints -bor
            [System.Xml.Schema.XmlSchemaValidationFlags]::ProcessSchemaLocation -bor 
            [System.Xml.Schema.XmlSchemaValidationFlags]::ReportValidationWarnings
        $readerSettings.Schemas.Add($Namespace, $SchemaFile) | Out-Null
        $readerSettings.add_ValidationEventHandler(
        {
            try {
                $detail = $_.Message 
                $detail += "`n" + "On Line: $($_.exception.linenumber) Offset: $($_.exception.lineposition)"
            } catch {}
            $failureMessages += $detail
            $failCount = $failCount + 1
        });
        try {
            $reader = [System.Xml.XmlReader]::Create($fileName, $readerSettings)
            while ($reader.Read()) { }
        }
        #handler to ensure we always close the reader sicne it locks files
        finally {
            $reader.Close()
        }
    } else {
        throw 'no input file'
    }
}

It works fine and I can validate XML files when XML and XSD schema are "real files". Now suppose both are stored in Variables: I've replaced

$reader = [System.Xml.XmlReader]::Create($fileName, $readerSettings)

with

$reader = [System.Xml.XmlReader]::Create((new-Object System.IO.StringReader($String)), $readerSettings)

which DO WORK, but StringReader 'collapses' all the properly formatted XML File to a single line, and hence the any Validation error is always on line 1.

Is there a way to make [System.Xml.XmlReader] process a Variable instead of a File while preserving the Formatting stored in the Variable?

Many thanks

1
  • I'm still actively looking for an answer...
    – Aldo
    Commented Feb 13, 2018 at 16:29

1 Answer 1

0

I don't think that you can preserve the formatting, but you can reformat it:

$StringWriter  = New-Object System.IO.StringWriter
$XmlTextWriter = New-Object System.XMl.XmlTextWriter $StringWriter
$XmlTextWriter.Formatting = "Indented"      # Default: None
$XmlTextWriter.Indentation = 2              # Default: 2
$XmlTextWriter.IndentChar = " "             # Default: Space
$String.WriteContentTo($XmlTextWriter)
"$StringWriter"
3
  • Sorry but I don't get it: I have an [XML]$Variable, which does contain proper formatting when casted .ToString() or .Save. How does a StringWriter come into play in this scenario? (I'm using a StringReader to 'trick' XmlReader into accepting a variable instead of a file)
    – Aldo
    Commented Nov 29, 2017 at 14:20
  • You wrote: "StringReader 'collapses' all the properly formatted XML File to a single line, and hence the any Validation error is always on line 1.", so I gave you a way to expand and reformat it. Anyway, I do not see how XML formatting could impact the validation of an XML string (do you have an example of an error?). Btw. you should just be able to validate XML strings (including proper XSD strings. I confirmed this on the "shiporder.xsd" file/string at w3schools.com/xml/schema_example.asp) using: $Reader = [xml]$String. (Or do I still miss something?)
    – iRon
    Commented Nov 29, 2017 at 15:24
  • XML Formatting does not impact validation. But if the validated XML is taken from a stringreader, it is validated as a single, very long row. Hence, an error that is on [Row 40, position 30], becomes [Row 1, position 341] (just as an example). Re-formatting xml is an option, but the given XML may not have the same number of rows (or character positions) as the original one, giving misleading indications of where the validation errors are. E.g., using the example above, [Row 40, position 30] may become [Row 39, position 28]
    – Aldo
    Commented Nov 30, 2017 at 12:57

Not the answer you're looking for? Browse other questions tagged or ask your own question.