Search code examples
xmlxsdxml-namespacesxsd-validationxml-validation

Validating XML document against XSD returns an error "element is not declared"


I am attempting to validate an XML document against an XSD document.

This is my XML:

 <?xml version="1.0" encoding="utf-8"?>
<ArrayOfProduct xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Product IdProduct="1" NameProduct="1" PriceProduct="1" availability="1" IdSup="1" />
</ArrayOfProduct>

And this is my XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.contoso.com/Products">
  <xs:element name="ArrayOfProduct">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Product"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="Product">
    <xs:complexType>
      <xs:attribute name="PriceProduct" use="required" type="xs:integer"/>
      <xs:attribute name="IdSup" use="required" type="xs:integer"/>
      <xs:attribute name="IdProduct" use="required" type="xs:integer"/>
      <xs:attribute name="NameProduct" use="required" type="xs:integer"/>
      <xs:attribute name="availability" use="required" type="xs:integer"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

And this is my c# code:

XmlReaderSettings ProductSettings = new XmlReaderSettings();
ProductSettings.Schemas.Add("http://www.contoso.com/Products", "XmlSchema.xsd");
ProductSettings.ValidationType = ValidationType.Schema;
ProductSettings.ValidationEventHandler += new ValidationEventHandler(ProductSettingsValidationEventHandler);
XmlReader Products = XmlReader.Create(doc + ".xml", ProductSettings);
while (Products.Read()) { }

Everytime I attempt to verify my XML document against my XSD document I get an error:

The Product element is not declared.


Solution

  • If you make these two changes, your XML will be valid according to your XSD:

    1. Add a default namespace to your XML to match the XSD's targetNamespace.
    2. Adjust the ref="Product" reference in your XSD to include a namespace prefix for the XSD's targetNamespace.

    XML

    <?xml version="1.0" encoding="utf-8"?>
    <ArrayOfProduct xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                    xmlns="http://www.contoso.com/Products">
        <Product IdProduct="1" NameProduct="1" 
                 PriceProduct="1" availability="1" IdSup="1" />
    </ArrayOfProduct>
    

    XSD

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
               elementFormDefault="qualified" 
               targetNamespace="http://www.contoso.com/Products"
               xmlns:p="http://www.contoso.com/Products">
      <xs:element name="ArrayOfProduct">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="p:Product"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="Product">
        <xs:complexType>
          <xs:attribute name="PriceProduct" use="required" type="xs:integer"/>
          <xs:attribute name="IdSup" use="required" type="xs:integer"/>
          <xs:attribute name="IdProduct" use="required" type="xs:integer"/>
          <xs:attribute name="NameProduct" use="required" type="xs:integer"/>
          <xs:attribute name="availability" use="required" type="xs:integer"/>
        </xs:complexType>
      </xs:element>
    </xs:schema>