Sto lavorando a un progetto in cui ho bisogno di generare file XML basati su XSD nidificati. per esempio. L'ORDINE ha un riferimento a PERSON, PERSONA ha un riferimento a INDIRIZZO, ecc.Come posso risolvere l'attributo schemaLocation di un file .XSD quando tutti i file .XSD sono archiviati come risorse?
Sto creando un'istanza `XmlReaderSettings 'per convalidare l'XSD, oltre a convalidare l'XML dopo che è stato generato.
Ho aggiunto gli XSD come risorse al mio assieme. Quindi creo un'istanza XmlSchema
per ogni risorsa, dal più basso al più alto e la aggiungo alla raccolta XmlReaderSettings.Schemas
.
Tuttavia, questo non riesce a tentare di aggiungere uno schema che fa riferimento a un altro schema. Ricevo una XmlSchemaException: "Per la dichiarazione dell'elemento, devono essere presenti il nome o l'attributo ref."
Ho incluso esempio di codice sorgente di sotto di XSD e:
ADDRESS.xsd - riferisce a Person.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ADDRESS.xsd" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="ADDRESS" >
<xs:complexType>
<xs:sequence>
<xs:element name="ADDRESS1" type="xs:string"/>
<xs:element name="ADDRESS2" type="xs:string"/>
<xs:element name="CITY" type="xs:string"/>
<xs:element name="STATE" type="xs:string"/>
<xs:element name="ZIP" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Person.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="PERSON.xsd" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="ADDRESS.xsd"/>
<xs:element name="PERSON" >
<xs:complexType>
<xs:sequence>
<xs:element name="L_NAME" type="xs:string"/>
<xs:element name="F_NAME" type="xs:string"/>
<xs:element name="Addresses">
<xs:complexType>
<xs:sequence>
<xs:element ref="ADDRESS" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Campione Codice - Carica e convalida XSD's
using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using SchemaTest.Properties;
namespace SchemaTest
{
class Program
{
static void Main(string[] args)
{
// create validation settings instance
var xmlReaderSettings = new XmlReaderSettings
{
ValidationType = ValidationType.Schema,
ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema |
XmlSchemaValidationFlags.ProcessSchemaLocation |
XmlSchemaValidationFlags.ReportValidationWarnings
};
xmlReaderSettings.ValidationEventHandler += SchemaValidationEventHandler;
// added XmlResourceResolver, per the accepted answer below
xMLReaderSettings.Schemas.XmlResolver = new XmlResourceResolver();
// load schemas into validation settings instance
LoadSchema(xmlReaderSettings, Resources.PERSON);
// validate schemas
xmlReaderSettings.Schemas.Compile();
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
private static void LoadSchema(XmlReaderSettings xmlReaderSettings, string schemaString)
{
using (var schemaStream = new MemoryStream(Encoding.Default.GetBytes(schemaString)))
{
var schema = XmlSchema.Read(schemaStream, null);
try
{
xmlReaderSettings.Schemas.Add(schema);
}
catch (Exception ex)
{
Console.WriteLine("EXCEPTION: {0}", ex.Message);
}
}
}
private static void SchemaValidationEventHandler(object sender, ValidationEventArgs e)
{
Console.WriteLine("{0}: {1}", e.Severity, e.Message);
}
}
}
io non sono sicuro se questo ha qualcosa a che fare con il ValidationFlags
, ma ho provato a rimuovere XmlSchemaValidationFlags.ProcessSchemaLocation
e ancora ricevuto lo stesso errore. Ho anche provato a passare SchemaValidationEventHandler
al metodo XmlSchema.Read
(invece di null nel codice di esempio), e lo schema sembra essere stato creato correttamente, ma getta ancora l'eccezione quando tentano di aggiungerlo alla raccolta XmlReaderSettings.Schemas
.
EDIT - 2011.11.03
ho risolto questo problema (gioco di parole) per creare il mio XmlUrlResolver
discendente chiamato XmlResourceResolver
, sull'esempio XmlResolver
classe nella risposta accettato di seguito.
il 'XmlResolver' ha fatto il trucco. Ho usato il tuo esempio per creare il mio resolver personalizzato e ho rifattorizzato il mio codice per assegnare il resolver al mio set di schemi 'xmlReaderSettings.Schemas'. –