Hi All,
I have seen this type of question raised in various groups but no one has supplied a definitive answer. I am trying to load a dataset schema that has an xs:include. Project policy is to have all schemas as embedded resources but there appears to be no means by which the DataSet.ReadXmlSchema method can be induced to use a custom Xmlresolver in order to supply the embedded referenced schema.
I have tried passing a custom resolver to an XmlTextReader and then loading the schema using the reader however the resolver is never fired. I suspect the resolver when used in conjunction with the XmlTextReader is looking for Xml external references such as document("blah") and just sees the <xs:include /> tag as a perfectly legitimate tag for the XSD schema.
I have tried passing the Schema to a XmlSchemaCollection first. This will indeed fire my custom resolver and set up the schema correctly, however there does not appear to be a way to impose this combined schema on the dataset.
I have tried streaming the schema back from the XmlSchemaCollection and then loading it but the <xs:include/> remains as an include tag.
I'm down to performing either a transformation, manual xml munge or even a string replacement to insert the included schema within the parent prior to providing it to the DataSet.ReadXmlSchema method. Ugh!
Any one out there either have an answer or a definitive 'it can't be done' or at least not within a reasonable effort?
Cheers
Patrick Kearney
Sample code only:
DataSet ds = new DataSet()
// lots of options to load schema
// ds.ReadXmlSchema(stream|XmlReader|TextReader|fileP ath|)
// go with XmlTextReader
XmlTextReader rdr = new XmlTextReader(myStream);
// supply my custom resolver that when called knows how to get the
// xsd from the Assembly resources
rdr.XmlResolver = new CustomResolver();
// resolver is not called and schema fails to load because a type is
// not defined (unless the referenced schema is placed within the
// application directory in which case it loads fine, the method must be using
// the XmlUrlResolver under the covers)
ds.ReadXmlSchema(rdr);
// Options to overcome behaviour
// create the reader
XmlTextReader rdr = new XmlTextReader(XSDStream);
XmlSchemaCollection sc = new XmlSchemaCollection();
// load the schema to a collection to force the xs:include to be processed
// custom resolver is called and referenced xsd supplied as a stream
sc.Add("myId", rdr, resolver);
// the schema now has an include collection properly populated with the
// referenced schema, however I can't see a way to pass this schema
// to the dataset
XmlSchema sch = sc["myId"];
// pull out the parent schema
System.Text.StringBuilder sb = new System.Text.StringBuilder();
StringWriter sw = new StringWriter(sb);
sch.Write(sw);
sw.Flush();
// string containing the parent
string parentSchema = sb.ToString();
// pull out the referenced schema
XmlSchemaExternal es = ((XmlSchemaExternal)sch.Includes[0]);
System.Text.StringBuilder sbe = new System.Text.StringBuilder();
StringWriter swe = new StringWriter(sbe);
es.Schema.Write(swe);
swe.Flush();
// string containing the referenced schema
string includeSchema = sbe.ToString();
// I know I could get the contents out more effeciently but this is just to demo,
// from here I could clearly load these strings into xml docs and combine them
// as if they were one schema however this all seems like too much work,
// especially if you consider several levels of referencing.
// Every other schema loading mechanism I have seen in the framework allows
// for a custom resolver to be passed.....what am I missing?