XmlSchemaElement exe = FindElement (schema.Items, einfo.ElementName);
XmlSchemaElement elem;
+ XmlSchemaObjectContainer container = null;
+ // In encoded format, the schema elements are not needed
+ if (!encodedFormat)
+ container = new XmlSchemaObjectContainer (schema);
+
Type memType = member.GetType();
if (member is XmlTypeMapMemberFlatList)
throw new InvalidOperationException ("Unwrapped arrays not supported as parameters");
else if (memType == typeof(XmlTypeMapMemberElement))
- elem = (XmlSchemaElement) GetSchemaElement (schema, einfo, member.DefaultValue, false);
+ elem = (XmlSchemaElement) GetSchemaElement (schema,
+ einfo, member.DefaultValue, false, container);
else
- elem = (XmlSchemaElement) GetSchemaElement (schema, einfo, false);
-
- // In encoded format, the schema elements are not needed
- if (!encodedFormat)
- schema.Items.Add (elem);
+ elem = (XmlSchemaElement) GetSchemaElement (schema,
+ einfo, false, container);
if (exe != null)
{
if (xmlTypeMapping.TypeData.IsComplexType)
einfo.MappedType = xmlTypeMapping;
einfo.IsNullable = false;
- schema.Items.Add (GetSchemaElement (schema, einfo, false));
+ GetSchemaElement (schema, einfo, false, new XmlSchemaObjectContainer (schema));
SetElementExported (xmlTypeMapping);
}
CompileSchemas ();
}
+ void ExportXmlSerializableSchema (XmlSchema currentSchema, XmlSerializableMapping map)
+ {
+ if (IsMapExported (map)) return;
+ SetMapExported (map);
+
+ if (map.Schema == null) return;
+
+ string targetNs = map.Schema.TargetNamespace;
+ XmlSchema existingSchema = schemas [targetNs];
+ if (existingSchema == null)
+ {
+ schemas.Add (map.Schema);
+ ImportNamespace (currentSchema, targetNs);
+ }
+ else if (existingSchema != map.Schema)
+ {
+ throw new InvalidOperationException("The namespace '" + targetNs +"' defined by the class '" + map.TypeFullName + "' is a duplicate.");
+ }
+ }
+
void ExportClassSchema (XmlTypeMapping map)
{
if (IsMapExported (map)) return;
ext.AnyAttribute = anyAttribute;
if (map.BaseMap == null)
ext.BaseTypeName = cmap.SimpleContentBaseType;
- else
+ else {
ext.BaseTypeName = new XmlQualifiedName (map.BaseMap.XmlType, map.BaseMap.XmlTypeNamespace);
+ ImportNamespace (schema, map.BaseMap.XmlTypeNamespace);
+ ExportClassSchema (map.BaseMap);
+ }
}
else if (map.BaseMap != null && map.BaseMap.IncludeInSchema)
{
ExportMembersMapSchema (schema, cmap, map.BaseMap, ext.Attributes, out particle, out anyAttribute);
ext.Particle = particle;
ext.AnyAttribute = anyAttribute;
- stype.IsMixed = cmap.XmlTextCollector != null;
+ stype.IsMixed = HasMixedContent (map);
+ cstype.IsMixed = BaseHasMixedContent (map);
ImportNamespace (schema, map.BaseMap.XmlTypeNamespace);
ExportClassSchema (map.BaseMap);
foreach (XmlTypeMapping dmap in map.DerivedTypes)
if (dmap.TypeData.SchemaType == SchemaTypes.Class) ExportClassSchema (dmap);
}
+
+ bool BaseHasMixedContent (XmlTypeMapping map)
+ {
+ ClassMap cmap = (ClassMap)map.ObjectMap;
+ return (cmap.XmlTextCollector != null && (map.BaseMap != null && DefinedInBaseMap (map.BaseMap, cmap.XmlTextCollector)));
+ }
+
+ bool HasMixedContent (XmlTypeMapping map)
+ {
+ ClassMap cmap = (ClassMap)map.ObjectMap;
+ return (cmap.XmlTextCollector != null && (map.BaseMap == null || !DefinedInBaseMap (map.BaseMap, cmap.XmlTextCollector)));
+ }
void ExportMembersMapSchema (XmlSchema schema, ClassMap map, XmlTypeMapping baseMap, XmlSchemaObjectCollection outAttributes, out XmlSchemaSequence particle, out XmlSchemaAnyAttribute anyAttribute)
{
}
else if (memType == typeof(XmlTypeMapMemberElement))
{
- seq.Items.Add (GetSchemaElement (schema, (XmlTypeMapElementInfo) member.ElementInfo [0], member.DefaultValue, true));
+ GetSchemaElement (schema, (XmlTypeMapElementInfo) member.ElementInfo [0],
+ member.DefaultValue, true, new XmlSchemaObjectContainer (seq));
}
else
{
- seq.Items.Add (GetSchemaElement (schema, (XmlTypeMapElementInfo) member.ElementInfo [0], true));
+ GetSchemaElement (schema, (XmlTypeMapElementInfo) member.ElementInfo[0],
+ true, new XmlSchemaObjectContainer (seq));
}
}
}
XmlSchemaParticle GetSchemaElement (XmlSchema currentSchema, XmlTypeMapElementInfo einfo, bool isTypeMember)
{
- return GetSchemaElement (currentSchema, einfo, System.DBNull.Value, isTypeMember);
+ return GetSchemaElement (currentSchema, einfo, System.DBNull.Value,
+ isTypeMember, (XmlSchemaObjectContainer) null);
}
- XmlSchemaParticle GetSchemaElement (XmlSchema currentSchema, XmlTypeMapElementInfo einfo, object defaultValue, bool isTypeMember)
+ XmlSchemaParticle GetSchemaElement (XmlSchema currentSchema, XmlTypeMapElementInfo einfo, bool isTypeMember, XmlSchemaObjectContainer container)
+ {
+ return GetSchemaElement (currentSchema, einfo, System.DBNull.Value, isTypeMember, container);
+ }
+
+ XmlSchemaParticle GetSchemaElement (XmlSchema currentSchema, XmlTypeMapElementInfo einfo, object defaultValue, bool isTypeMember, XmlSchemaObjectContainer container)
{
if (einfo.IsTextElement) return null;
XmlSchemaAny any = new XmlSchemaAny ();
any.MinOccurs = 0;
any.MaxOccurs = 1;
+ if (container != null)
+ container.Items.Add (any);
return any;
}
XmlSchemaElement selem = new XmlSchemaElement ();
+ if (container != null)
+ container.Items.Add (selem);
if (isTypeMember)
{
{
if (isTypeMember) selem.IsNillable = einfo.IsNullable;
selem.Name = einfo.ElementName;
- XmlQualifiedName typeName = new XmlQualifiedName (einfo.TypeData.XmlType, einfo.DataTypeNamespace);
if (defaultValue != System.DBNull.Value)
selem.DefaultValue = XmlCustomFormatter.ToXmlString (einfo.TypeData, defaultValue);
break;
case SchemaTypes.XmlSerializable:
- selem.SchemaType = GetSchemaXmlSerializableType ();
+ selem.SchemaType = GetSchemaXmlSerializableType (einfo.MappedType as XmlSerializableMapping);
+ ExportXmlSerializableSchema (currentSchema, einfo.MappedType as XmlSerializableMapping);
break;
case SchemaTypes.Enum:
break;
case SchemaTypes.Primitive:
- selem.SchemaTypeName = new XmlQualifiedName (einfo.TypeData.XmlType, einfo.DataTypeNamespace);;
+ selem.SchemaTypeName = new XmlQualifiedName (einfo.TypeData.XmlType, einfo.DataTypeNamespace);
+ if (!einfo.TypeData.IsXsdType) {
+ ImportNamespace (currentSchema, einfo.MappedType.XmlTypeNamespace);
+ ExportDerivedSchema (einfo.MappedType);
+ }
break;
}
}
foreach (XmlSchemaObject ob in memberSchema.Items)
if (ob is XmlSchemaElement && ((XmlSchemaElement)ob).Name == einfo.ElementName)
return selem;
-
- memberSchema.Items.Add (GetSchemaElement (memberSchema, einfo, defaultValue, false));
+
+ GetSchemaElement (memberSchema, einfo, defaultValue, false,
+ new XmlSchemaObjectContainer (memberSchema));
}
return selem;
}
void ImportNamespace (XmlSchema schema, string ns)
{
- if (ns == "" || ns == schema.TargetNamespace || ns == XmlSchema.Namespace) return;
+ if (ns == null || ns.Length == 0 ||
+ ns == schema.TargetNamespace || ns == XmlSchema.Namespace) return;
foreach (XmlSchemaObject sob in schema.Includes)
if ((sob is XmlSchemaImport) && ((XmlSchemaImport)sob).Namespace == ns) return;
return stype;
}
- XmlSchemaType GetSchemaXmlSerializableType ()
+ XmlSchemaType GetSchemaXmlSerializableType (XmlSerializableMapping map)
{
XmlSchemaComplexType stype = new XmlSchemaComplexType ();
XmlSchemaSequence seq = new XmlSchemaSequence ();
- XmlSchemaElement selem = new XmlSchemaElement ();
- selem.RefName = new XmlQualifiedName ("schema",XmlSchema.Namespace);
- seq.Items.Add (selem);
- seq.Items.Add (new XmlSchemaAny ());
+ if (map.Schema == null) {
+ XmlSchemaElement selem = new XmlSchemaElement ();
+ selem.RefName = new XmlQualifiedName ("schema",XmlSchema.Namespace);
+ seq.Items.Add (selem);
+ seq.Items.Add (new XmlSchemaAny ());
+ } else {
+ XmlSchemaAny any = new XmlSchemaAny ();
+ any.Namespace = map.Schema.TargetNamespace;
+ seq.Items.Add (any);
+ }
stype.Particle = seq;
return stype;
}
}
}
+ void ExportDerivedSchema(XmlTypeMapping map) {
+ if (IsMapExported (map)) return;
+ SetMapExported (map);
+
+ XmlSchema schema = GetSchema (map.XmlTypeNamespace);
+ XmlSchemaSimpleType stype = new XmlSchemaSimpleType ();
+ stype.Name = map.ElementName;
+ schema.Items.Add (stype);
+
+ XmlSchemaSimpleTypeRestriction rest = new XmlSchemaSimpleTypeRestriction ();
+ rest.BaseTypeName = new XmlQualifiedName (map.TypeData.MappedType.XmlType, XmlSchema.Namespace);
+ XmlSchemaPatternFacet facet = map.TypeData.XmlSchemaPatternFacet;
+ if (facet != null)
+ rest.Facets.Add(facet);
+ stype.Content = rest;
+ }
+
void ExportEnumSchema (XmlTypeMapping map)
{
if (IsMapExported (map)) return;
if (schema == null)
{
schema = new XmlSchema ();
- schema.TargetNamespace = ns;
+ if (ns != null && ns.Length > 0)
+ schema.TargetNamespace = ns;
if (!encodedFormat)
schema.ElementFormDefault = XmlSchemaForm.Qualified;
schemas.Add (schema);
}
#endregion // Methods
+
+ private class XmlSchemaObjectContainer
+ {
+ private readonly XmlSchemaObject _xmlSchemaObject;
+
+ public XmlSchemaObjectContainer (XmlSchema schema)
+ {
+ _xmlSchemaObject = schema;
+ }
+
+ public XmlSchemaObjectContainer (XmlSchemaGroupBase group)
+ {
+ _xmlSchemaObject = group;
+ }
+
+ public XmlSchemaObjectCollection Items {
+ get {
+ if (_xmlSchemaObject is XmlSchema) {
+ return ((XmlSchema) _xmlSchemaObject).Items;
+ } else {
+ return ((XmlSchemaGroupBase) _xmlSchemaObject).Items;
+ }
+ }
+ }
+ }
}
}