7
votes

I am using a nested XSD schema to validate an XML document. The imported XSDs use their own target namespaces and I can validate the sample XML given below using Liquid XML Studio. But when I run the validation using my C# code below, it fails with the type declaration error (see below). I have spend alot of time trying to figure out, but no luck:

Main XSD Schema (DataItem.xsd):

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:DataNumeric="Doc.DataNumeric" xmlns:DataYesNo="Doc.DataYesNo"  attributeFormDefault="qualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import schemaLocation="DataNumeric.xsd" namespace="Doc.DataNumeric" />
  <xs:import schemaLocation="DataYesNo.xsd" namespace="Doc.DataYesNo" />
  <xs:complexType name="tDataItem">
      <xs:choice>
        <xs:element name="DataNumeric" type="DataNumeric:tDataNumeric" />
        <xs:element name="DataYesNo" type="DataYesNo:tDataYesNo" />
      </xs:choice>
  </xs:complexType>
  <xs:element name="DataItem" type="tDataItem" />  
</xs:schema>

Included XSD Schema (DataNumeric.xsd):

**<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:DataNumeric="Doc.DataNumeric" elementFormDefault="qualified" targetNamespace="Doc.DataNumeric" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="tDataNumeric">
    <xs:sequence>
      <xs:element name="Answer" type="xs:double" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="DataNumeric" type="DataNumeric:tDataNumeric" />
</xs:schema>**

The XML:

<DataItem>
  <DataNumeric xmlns:DataNumeric="Doc.DataNumeric">
    <DataNumeric:Answer>37.8</DataNumeric:Answer>
  </DataNumeric>
</DataItem>

Validation Error:

XmlSchemaValidationException: Type 'Doc.DataNumeric:tDataNumeric' is not declared.

C# Validation Code:

XDocument xDoc = XDocument.Parse(xxxxxxx);
string xsdPath = ConfigUtils.GetXsdPath(XsdSchemaIdentifier.HHDataItem);
FileStream fs = new FileStream(xsdPath, FileMode.Open);
XmlReader reader = XmlReader.Create(fs);
XmlSchemaSet xss = new XmlSchemaSet();
xss.Add("", reader);
fs.Close();
fs.Dispose();

xDoc.Validate(xss, null);
2

2 Answers

5
votes

I have found the problem after a frustrating day and a half of iterations. Changing:

FileStream fs = new FileStream(xsdPath, FileMode.Open);
XmlReader reader = XmlReader.Create(fs);
XmlSchemaSet xss = new XmlSchemaSet();
xss.Add("", reader);

to

XmlSchemaSet xss = new XmlSchemaSet();
xss.Add("", xsdPath);

solved the problem. However I am still looking for the answer to WHY? Both are valid ways of adding a schema to the schema set (i.e. 2 overloads).

2
votes

arootbeer is right about how your xsd imports another xsd. However another solution is to add the the imported xsd into the XmlSchemaSet first, then add the xsd that is doing the actual importing.

//Xsd file that is being imported
FileStream importedXsdStream = new FileStream(importedXsdPath, FileMode.Open);
XmlReader xmlReader = XmlReader.Create(importedXsdStream);
XmlSchemaSet xmlSchemaSet = new XmlSchemaSet();
xmlSchemaSet.Add("NameSpace.SomeNameSpace", xmlReader);

//Your code
FileStream fs = new FileStream(xsdPath, FileMode.Open);
XmlReader reader = XmlReader.Create(fs);
XmlSchemaSet xss = new XmlSchemaSet();
xss.Add("", reader);

Notice I put the Namespace as the first parameter when adding the imported xsd to the XmlSchemaSet. This may be necessary depending on if there are errors with the target namespace not matching the namespace provided in the imported xsd.