using Use = System.Xml.Schema.XmlSchemaUse;
using SOMList = System.Xml.Schema.XmlSchemaObjectCollection;
using SOMObject = System.Xml.Schema.XmlSchemaObject;
+using Import = System.Xml.Schema.XmlSchemaImport;
using Element = System.Xml.Schema.XmlSchemaElement;
using Attr = System.Xml.Schema.XmlSchemaAttribute;
using AttrGroup = System.Xml.Schema.XmlSchemaAttributeGroup;
namespace System.Xml.Schema
{
- [MonoTODO ("merge primitive types; infer gYearMonth too; in some cases sequence should contain element whose minOccurs=0 (no obvious rules right now); reject some non-supported schema components")]
- public class XmlSchemaInference
+ [MonoTODO]
+ // FIXME:
+ // - merge primitive types
+ // - infer gYearMonth too
+ // - in some cases sequence should contain element whose minOccurs=0
+ // (no obvious rules right now)
+ // - reject some non-supported schema components
+ public sealed class XmlSchemaInference
{
public enum InferenceOption {
Restricted,
}
public InferenceOption TypeInference {
- get { return TypeInference; }
+ get { return typeInference; }
set { typeInference = value; }
}
- public XmlSchemaSet InferSchema (XmlReader xmlReader)
+ public XmlSchemaSet InferSchema (XmlReader instanceDocument)
{
- return InferSchema (xmlReader, new XmlSchemaSet ());
+ return InferSchema (instanceDocument, new XmlSchemaSet ());
}
- public XmlSchemaSet InferSchema (XmlReader xmlReader,
+ public XmlSchemaSet InferSchema (XmlReader instanceDocument,
XmlSchemaSet schemas)
{
- return XsdInference.Process (xmlReader, schemas,
+ return XsdInference.Process (instanceDocument, schemas,
occurrence == InferenceOption.Relaxed,
typeInference == InferenceOption.Relaxed);
}
{
public static XmlSchemaSet Process (XmlReader xmlReader,
XmlSchemaSet schemas,
- bool laxOccurence,
+ bool laxOccurrence,
bool laxTypeInference)
{
XsdInference impl = new XsdInference (xmlReader,
- schemas, laxOccurence, laxTypeInference);
+ schemas, laxOccurrence, laxTypeInference);
impl.Run ();
return impl.schemas;
}
static readonly QName QNameDecimal = new QName (
"decimal", XmlSchema.Namespace);
- static readonly QName QNameUDecimal = new QName (
- "unsignedDecimal", XmlSchema.Namespace);
-
static readonly QName QNameDouble = new QName (
"double", XmlSchema.Namespace);
XmlReader source;
XmlSchemaSet schemas;
- bool laxOccurence;
+ bool laxOccurrence;
bool laxTypeInference;
Hashtable newElements = new Hashtable ();
private XsdInference (XmlReader xmlReader,
XmlSchemaSet schemas,
- bool laxOccurence,
+ bool laxOccurrence,
bool laxTypeInference)
{
this.source = xmlReader;
this.schemas = schemas;
- this.laxOccurence = laxOccurence;
+ this.laxOccurrence = laxOccurrence;
this.laxTypeInference = laxTypeInference;
}
// move to top-level element
source.MoveToContent ();
- int depth = source.Depth;
if (source.NodeType != XmlNodeType.Element)
throw new ArgumentException ("Argument XmlReader content is expected to be an element.");
else
InferElement (el, qname.Namespace, false);
- // finally compile again.
- schemas.Compile ();
+ // FIXME: compile again.
+// foreach (XmlSchema schema in schemas.Schemas ())
+// schemas.Reprocess (schema);
+ }
+
+ private void AddImport (string current, string import)
+ {
+ foreach (XmlSchema schema in schemas.Schemas (current)) {
+ bool exists = false;
+ foreach (XmlSchemaExternal e in schema.Includes) {
+ Import imp = e as Import;
+ if (imp != null &&
+ imp.Namespace == import)
+ exists = true;
+ }
+ if (exists)
+ continue;
+ Import newimp = new Import ();
+ newimp.Namespace = import;
+ schema.Includes.Add (newimp);
+ }
}
private void IncludeXmlAttributes ()
Attr attr = table [attrName] as Attr;
if (attr == null) {
attList.Add (InferNewAttribute (
- attrName, isNew));
+ attrName, isNew, ns));
} else {
table.Remove (attrName);
if (attr.RefName != null &&
}
private XmlSchemaAttribute InferNewAttribute (
- QName attrName, bool isNewTypeDefinition)
+ QName attrName, bool isNewTypeDefinition, string ns)
{
Attr attr = null;
bool mergedRequired = false;
}
attr = new Attr ();
attr.RefName = attrName;
+ AddImport (ns, attrName.Namespace);
} else {
// local attribute
attr = new Attr ();
attr.SchemaTypeName =
InferSimpleType (source.Value);
}
- if (!laxOccurence &&
+ if (!laxOccurrence &&
(isNewTypeDefinition || mergedRequired))
attr.Use = Use.Required;
else
Element nel = new Element ();
if (source.NamespaceURI == ns)
nel.Name = source.LocalName;
- else
+ else {
nel.RefName = new QName (source.LocalName,
source.NamespaceURI);
+ AddImport (ns, source.NamespaceURI);
+ }
InferElement (nel, source.NamespaceURI, true);
c.Items.Add (nel);
}
QName name = new QName (source.LocalName,
source.NamespaceURI);
Element nel = CreateElement (name);
+ if (laxOccurrence)
+ nel.MinOccurs = 0;
InferElement (nel, ns, true);
if (ns == name.Namespace)
s.Items.Add (nel);
else {
Element re = new Element ();
+ if (laxOccurrence)
+ re.MinOccurs = 0;
re.RefName = name;
+ AddImport (ns, name.Namespace);
s.Items.Add (re);
}
consumed = true;
private Choice ToSequenceOfChoice (Sequence s)
{
Choice c = new Choice ();
- if (laxOccurence)
+ if (laxOccurrence)
c.MinOccurs = 0;
c.MaxOccursString = "unbounded";
foreach (Particle p in s.Items)
private Sequence CreateSequence ()
{
Sequence s = new Sequence ();
- if (laxOccurence)
+ if (laxOccurrence)
s.MinOccurs = 0;
return s;
}
return QNameString;
switch (value) {
- // 0 and 1 are not infered as byte unlike MS.XSDInfer
+ // 0 and 1 are not inferred as byte unlike MS.XSDInfer
// case "0":
// case "1":
case "true":