2011-09-21 38 views
5

Estoy utilizando un esquema XSD anidado para validar un documento XML. Los XSD importados usan sus propios espacios de nombres de destino y puedo validar el XML de muestra que se proporciona a continuación utilizando Liquid XML Studio. Pero cuando ejecuto la validación utilizando mi código C# a continuación, falla con el error de declaración de tipo (ver a continuación). Tengo pasar mucho tiempo tratando de averiguar, pero no hubo suerte:Error de validación XML con el esquema XSD anidado - Tipo no declarado

principal esquema XSD (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> 

Incluido esquema XSD (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>** 

El XML:

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

Error de validación:

XmlSchemaValidationException: Tipo 'Doc.DataNumeric: tDataNumeric' no se ha declarado.

C# Código de Validación:

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); 

Respuesta

5

he encontrado el problema después de un día frustrante y medio de iteraciones. Cambiante:

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

a

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

resolvió el problema. Sin embargo, todavía estoy buscando la respuesta a POR QUÉ? Ambas son formas válidas de agregar un esquema al conjunto de esquemas (es decir, 2 sobrecargas).

+5

La razón por la que falla es porque su XSD importa otros XSD. Cuando usa un 'XmlReader', no tiene idea de la ubicación de la entrada del' Stream' subyacente, y por lo tanto no tiene forma de encontrar las importaciones. Cuando proporciona la ruta al archivo de esquema al 'XmlSchemaSet', puede hacer su propio trabajo de localización basado en esa ruta. – arootbeer

1

arootbeer tiene razón acerca de cómo su xsd importa otro xsd. Sin embargo, otra solución es agregar primero el xsd importado al XmlSchemaSet, luego agregar el xsd que está haciendo la importación real.

//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); 

Aviso pongo el espacio de nombres como el primer parámetro al añadir el XSD importados a XmlSchemaSet. Esto puede ser necesario dependiendo de si hay errores con el espacio de nombres de destino que no coincida con el espacio de nombres provisto en el xsd importado.

Cuestiones relacionadas