Howto detect violation of xsd:unique constraint via XmlReader ValidationType.Schema

24 Views Asked by At

The following demo code validates if a XML matches a given XSD. But it does not detect if the XML violates any xsd:unique constraints. Why is that and more importantly, how can I validate unique constraints?

using var schemaReader = XmlReader.Create(pathToXsd);

var validationErrors = new StringBuilder();

var readerSettings = new XmlReaderSettings();
readerSettings.Schemas.Add(targetNamespace, schemaReader);
readerSettings.ValidationType = ValidationType.Schema;
readerSettings.ValidationEventHandler += (s, e) => validationErrors.AppendLine($"{e.Severity} {e.Message}");
using var reader = XmlReader.Create(pathToXml, readerSettings);

while (reader.Read())
{
    // Read the whole xml file just for invoking validation.
}

if (validationErrors.Length == 0)
   throw new Exception("given XML should violate us:unique constraint");

The demo XSD (borrowed from how to make an attribute unique in xml schema?)

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns="http://Test.xsd"
  targetNamespace="http://Test.xsd"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  elementFormDefault="qualified">
  <xsd:element name="books">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="book" maxOccurs="unbounded">
          <xsd:complexType>
            <xsd:attribute name="isbn" type="xsd:string" />
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
    <xsd:unique name="unique-isbn">
      <xsd:selector xpath="book" />
      <xsd:field xpath="@isbn" />
    </xsd:unique>
  </xsd:element>
</xsd:schema>

The demo XML

    <books xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://Test.xsd">
    <book isbn="abc"/>
    <book isbn="def"/>
    <book isbn="def"/><!-- this line should raise an error -->
</books>
1

There are 1 best solutions below

2
Martin Honnen On

Make sure you set the validation flag to ProcessIdentityConstraints https://learn.microsoft.com/en-us/dotnet/api/system.xml.schema.xmlschemavalidationflags?view=net-8.0.

readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ProcessIdentityConstraints

See also the comment about the namespace issue.