1

I have been trying to figure out how to accurately validate this XML, it looks like it shouldn't be passing validation but it is. I have tried a C# implementation and a powershell implementation, both pass but should not. For reference, my XSD imports 4 other XSDs but I have attached the relevant parts for brevity;

Basic C# validation

    class XmlSchemaSetExample
    {
        static void Main()
        {
            XmlReaderSettings xmlSettings = new XmlReaderSettings();
            xmlSettings.Schemas.Add("http://url.org/Contract", @"C:\XML\Contract.xsd");
            xmlSettings.ValidationType = ValidationType.Schema;
            xmlSettings.ValidationEventHandler += new ValidationEventHandler(xmlSettingsValidator);


            XmlReader xml = XmlReader.Create(@"C:\XML\response2.xml", xmlSettings);

            while (xml.Read()) { }
        }

        static void xmlSettingsValidator(object sender, ValidationEventArgs e)
        {
            if (e.Severity == XmlSeverityType.Warning)
            {
                Console.Write("WARNING: ");
                Console.WriteLine(e.Message);
            }
            else if (e.Severity == XmlSeverityType.Error)
            {
                Console.Write("ERROR: ");
                Console.WriteLine(e.Message);
            }
        }
    }

I have tried other XSD/XML combinations and I can trigger a failure but I cannot trigger a failure with this specific XSD/XML payload -- where the ErrorDetail tag should trigger a validation error with ErrorDetailFault in the XML instead of the defined tag. However, I cannot find a way to trigger this validation error. I am defining the ErrorDetail complex type and then referencing the type in the XSD

XSD

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:tns="http://url.org/Contract" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://url.org/Contract" elementFormDefault="qualified">
    <xs:import namespace="http://schemas.microsoft.com/2003/10/Serialization/" schemaLocation="Serialization.xsd"/>
    <xs:complexType name="ErrorDetail">
        <xs:sequence>
            <xs:element name="Time" type="xs:dateTime" nillable="true" minOccurs="0"/>
            <xs:element name="ID" nillable="true" minOccurs="0">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:minLength value="0" fixed="false"/>
                        <xs:maxLength value="64" fixed="false"/>
                        <xs:whiteSpace value="preserve"/>
                        <xs:pattern value=".{0,64}"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
            <xs:element name="CallSite" nillable="true" minOccurs="0">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:minLength value="0" fixed="false"/>
                        <xs:maxLength value="64" fixed="false"/>
                        <xs:whiteSpace value="preserve"/>
                        <xs:pattern value=".{0,64}"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
            <xs:element name="Message" nillable="true" minOccurs="0">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:minLength value="0" fixed="false"/>
                        <xs:maxLength value="64" fixed="false"/>
                        <xs:whiteSpace value="preserve"/>
                        <xs:pattern value=".{0,64}"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
            <xs:element name="Exceptions" nillable="true" minOccurs="0">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:minLength value="0" fixed="false"/>
                        <xs:maxLength value="64" fixed="false"/>
                        <xs:whiteSpace value="preserve"/>
                        <xs:pattern value=".{0,64}"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
            <xs:element name="Tag1" nillable="true" minOccurs="0">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:minLength value="0" fixed="false"/>
                        <xs:maxLength value="64" fixed="false"/>
                        <xs:whiteSpace value="preserve"/>
                        <xs:pattern value=".{0,64}"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
            <xs:element name="Tag2" nillable="true" minOccurs="0">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:minLength value="0" fixed="false"/>
                        <xs:maxLength value="64" fixed="false"/>
                        <xs:whiteSpace value="preserve"/>
                        <xs:pattern value=".{0,64}"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="ErrorDetail" type="tns:ErrorDetail" nillable="true"/>
</xs:schema>

XML

        <ErrorDetailFault xmlns:a="http://url.org/Contract" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <a:Time>2022-01-31T19:15:50.324427Z</a:Time>
            <a:ID>b9201014-2b11-4523-a30c-55e3112d29d1</a:ID>
            <a:CallSite>data</a:CallSite>
            <a:Message/>
            <a:Exceptions>Exception</a:Exceptions>
            <a:Tag1>"data"</a:Tag1>
            <a:Tag2/>
        </ErrorDetailFault>

Any insights into what I've done incorrectly here?

Powershell validation attempt for additional context to troubleshooting this -- also passes on an expected failure

PS

function Test-XmlBySchema
{
    [CmdletBinding()]
    [OutputType([bool])]
    param
    (
        [Parameter(Mandatory)]
        [ValidateScript({ Test-Path -Path $_ })]
        [ValidatePattern('\.xml')]
        [string]$XmlFile,
        [Parameter(Mandatory)]
        [ValidateScript({ Test-Path -Path $_ })]
        [ValidatePattern('\.xsd')]
        [string]$SchemaPath,
        [string]$NSUri
    )

    try
    {
        [xml]$xml = Get-Content $XmlFile
        $xml.Schemas.Add($NSUri, $SchemaPath) | Out-Null
        $xml.Validate($null)
        Write-Verbose "Successfully validated $XmlFile against schema ($SchemaPath)"
        $result = $true
    }
    catch
    {
        $err = $_.Exception.Message
        $err
        Write-Verbose "Failed to validate $XmlFile against schema ($SchemaPath)`nDetails: $err"
        $result = $false
    }
    finally
    {
        $result
    }
}
0

1 Answer 1

2

In your XML, ErrorDetailFault,

    <ErrorDetailFault xmlns:a="http://url.org/Contract" 
                      xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

is not in the target namespace of the XSD, http://url.org/Contract.

To place ErrorDetailFault in the http://url.org/Contract namespace, add the a namespace prefix to the ErrorDetailFault:

    <a:ErrorDetailFault xmlns:a="http://url.org/Contract" 
                        xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

or have it be the default namespace (after removing the a prefix from the other elements in the coument):

    <ErrorDetailFault xmlns="http://url.org/Contract" 
                      xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
4
  • Thank you this is helpful for overall cleanup, I will be sure to make these changes. Although, this should definitely trigger a validation failure, yea? I can't seem to validate my XSD correctly because its always returning clean despite what you found + ErrorDetailFault should be ErrorDetail as defined in the XSD. Any general tips for XSD validation or tools I can look at?
    – Sean Kelly
    Commented Feb 1, 2022 at 20:06
  • Yes, without this change, validation should fail with a message complaining about not being able to find the declaration for the ErrorDetailFault element because a:ErrorDetailFault, which the XSD declares, is a different element.
    – kjhughes
    Commented Feb 1, 2022 at 20:18
  • It might be helpful to first check your XML against your XSD via an XML editor or command line validator. Once you've established that validation is working for both success and failure as expected, move on to replicating your results with your code. That way, you'll know whether to focus at the XML/XSD level or the code level.
    – kjhughes
    Commented Feb 1, 2022 at 20:20
  • 1
    @SeanKelly you would not expect an error in this case - the validator can't tell you the element is invalid because it's not in a namespace covered by the schema. You can turn on warnings (by setting XmlReaderSettings.ValidationFlags) and you'll get warnings like: 'Could not find schema information for the element 'ErrorDetailFault'.' Commented Feb 2, 2022 at 16:41

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