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>
Make sure you set the validation flag to
ProcessIdentityConstraintshttps://learn.microsoft.com/en-us/dotnet/api/system.xml.schema.xmlschemavalidationflags?view=net-8.0.See also the comment about the namespace issue.