Browse Source

* SerializationCodeGenerator.cs, XmlSerializationReaderInterpreter.cs:
When reading an object using the typeof(object) map, an emty xsi:type
means that it has to read the contents into an XmlNode[].
* TypeData.cs: Return the correct full name for inner classes.
* XmlSchemaImporter.cs: Improved detection of types that represent
"anyType", and must be mapped to XmlElement, XmlNode or Object.
* XmlSerializationReader.cs: In GetXsiType(), find the type attribute using
the correct namespace.
In ReadTypedPrimitive(), read the element as XmlNode[] if the type is
not known.

svn path=/trunk/mcs/; revision=26761

Lluis Sanchez 21 years ago
parent
commit
fb9c1efbf0

+ 13 - 0
mcs/class/System.XML/System.Xml.Serialization/ChangeLog

@@ -1,3 +1,16 @@
+2004-05-05  Lluis Sanchez Gual <[email protected]>
+
+	* SerializationCodeGenerator.cs, XmlSerializationReaderInterpreter.cs: 
+	  When reading an object using the typeof(object) map, an emty xsi:type 
+	  means that it has to read the contents into an XmlNode[].
+	* TypeData.cs: Return the correct full name for inner classes.
+	* XmlSchemaImporter.cs: Improved detection of types that represent 
+	  "anyType", and must be mapped to XmlElement, XmlNode or Object.
+	* XmlSerializationReader.cs: In GetXsiType(), find the type attribute using
+	  the correct namespace.
+	  In ReadTypedPrimitive(), read the element as XmlNode[] if the type is
+	  not known.
+
 2004-05-05  Atsushi Enomoto  <[email protected]>
 
 	* XmlSerializationWriter.cs : It do not have to handle schema

+ 7 - 8
mcs/class/System.XML/System.Xml.Serialization/SerializationCodeGenerator.cs

@@ -1252,26 +1252,25 @@ namespace System.Xml.Serialization
 			}
 			
 			WriteLine ("System.Xml.XmlQualifiedName t = GetXsiType();");
-			WriteLine ("if (t != null) ");
-			WriteLineInd ("{");
+			WriteLine ("if (t == null)");
+			if (typeMap.TypeData.Type != typeof(object))
+				WriteLine ("\t;");
+			else
+				WriteLine ("\treturn " + GetCast (typeMap.TypeData, "ReadTypedPrimitive (new System.Xml.XmlQualifiedName(\"anyType\", System.Xml.Schema.XmlSchema.Namespace))") + ";");
 			
-			bool first = true;
 			foreach (XmlTypeMapping realMap in typeMap.DerivedTypes)
 			{
-				WriteLineInd ((first?"":"else ") + "if (t.Name == " + GetLiteral (realMap.XmlType) + " && t.Namespace == " + GetLiteral (realMap.XmlTypeNamespace) + ")");
+				WriteLineInd ("else if (t.Name == " + GetLiteral (realMap.XmlType) + " && t.Namespace == " + GetLiteral (realMap.XmlTypeNamespace) + ")");
 				WriteLine ("return " + GetReadObjectCall(realMap, isNullable, checkType) + ";");
 				Unindent ();
-				first = false;
 			}
 
-			WriteLine ((first?"":"else ") + "if (t.Name != " + GetLiteral (typeMap.XmlType) + " || t.Namespace != " + GetLiteral (typeMap.XmlTypeNamespace) + ")");
+			WriteLine ("else if (t.Name != " + GetLiteral (typeMap.XmlType) + " || t.Namespace != " + GetLiteral (typeMap.XmlTypeNamespace) + ")");
 			if (typeMap.TypeData.Type == typeof(object))
 				WriteLine ("\treturn " + GetCast (typeMap.TypeData, "ReadTypedPrimitive (t)") + ";");
 			else
 				WriteLine ("\tthrow CreateUnknownTypeException(t);");
 
-			WriteLineUni ("}");
-			
 			if (!typeMap.TypeData.IsValueType)
 			{
 				if (_format == SerializationFormat.Literal)

+ 2 - 3
mcs/class/System.XML/System.Xml.Serialization/TypeData.cs

@@ -30,7 +30,7 @@ namespace System.Xml.Serialization
 			this.type = type;
 			this.elementName = elementName;
 			this.typeName = type.Name;
-			this.fullTypeName = type.FullName;
+			this.fullTypeName = type.FullName.Replace ('+', '.');
 
 			if (isPrimitive)
 				sType = SchemaTypes.Primitive;
@@ -53,7 +53,7 @@ namespace System.Xml.Serialization
 		{
 			this.elementName = xmlType;
 			this.typeName = typeName;
-			this.fullTypeName = fullTypeName;
+			this.fullTypeName = fullTypeName.Replace ('+', '.');
 			this.listItemTypeData = listItemTypeData;
 			this.sType = schemaType;
 		}
@@ -82,7 +82,6 @@ namespace System.Xml.Serialization
 		public string FullTypeName
 		{
 			get {
-//				return type.FullName.Replace ('+', '.');
 				return fullTypeName;
 			}
 		}

+ 31 - 7
mcs/class/System.XML/System.Xml.Serialization/XmlSchemaImporter.cs

@@ -411,6 +411,10 @@ namespace System.Xml.Serialization {
 			// the class map is registered before parsing the children. We can't do the same
 			// with the array type because to register the array map we need the type of the array.
 
+			Type anyType = GetAnyElementType (stype);
+			if (anyType != null)
+				return GetTypeMapping (TypeTranslator.GetTypeData(anyType));
+				
 			if (CanBeArray (typeQName, stype))
 			{
 				TypeData typeData;
@@ -424,13 +428,6 @@ namespace System.Xml.Serialization {
 
 				// After all, it is not an array. Create a class map then.
 			}
-			else if (CanBeAnyElement (stype))
-			{
-				if (stype.IsMixed)
-					return GetTypeMapping (TypeTranslator.GetTypeData(typeof(XmlNode)));
-				else
-					return GetTypeMapping (TypeTranslator.GetTypeData(typeof(XmlElement)));
-			}
 			else if (CanBeIXmlSerializable (stype))
 			{
 				return ImportXmlSerializableMapping (typeQName.Namespace);
@@ -1242,6 +1239,33 @@ namespace System.Xml.Serialization {
 			XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;
 			return (seq != null) && (seq.Items.Count == 1) && (seq.Items[0] is XmlSchemaAny);
 		}
+		
+		Type GetAnyElementType (XmlSchemaComplexType stype)
+		{
+			XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;
+			
+			if ((seq == null) || (seq.Items.Count != 1) || !(seq.Items[0] is XmlSchemaAny))
+				return null;
+			
+			if (encodedFormat) 
+				return typeof(object);
+
+			XmlSchemaAny any = seq.Items[0] as XmlSchemaAny;
+			if (any.MaxOccurs == 1)
+			{
+				if (stype.IsMixed)
+					return typeof(XmlNode);
+				else
+					return typeof(XmlElement);
+			}
+			else
+			{
+				if (stype.IsMixed)
+					return typeof(XmlNode[]);
+				else
+					return typeof(XmlElement[]);
+			}
+		}
 
 		bool CanBeIXmlSerializable (XmlSchemaComplexType stype)
 		{

+ 19 - 2
mcs/class/System.XML/System.Xml.Serialization/XmlSerializationReader.cs

@@ -273,7 +273,7 @@ namespace System.Xml.Serialization {
 
 		protected XmlQualifiedName GetXsiType ()
 		{
-			string typeName = Reader.GetAttribute ("xsi:type");
+			string typeName = Reader.GetAttribute ("type", XmlSchema.InstanceNamespace);
 			if (typeName == string.Empty || typeName == null) return null;
 			int i = typeName.IndexOf (":");
 			if (i == -1) return new XmlQualifiedName (typeName, Reader.NamespaceURI);
@@ -628,7 +628,24 @@ namespace System.Xml.Serialization {
 		{
 			if (qname == null) qname = GetXsiType ();
 			TypeData typeData = TypeTranslator.GetPrimitiveTypeData (qname.Name);
-			if (typeData == null || typeData.SchemaType != SchemaTypes.Primitive) throw new InvalidOperationException ("Unknown type: " + qname.Name);
+			if (typeData == null || typeData.SchemaType != SchemaTypes.Primitive)
+			{
+				// Put everything into a node array
+				XmlNode node = Document.ReadNode (reader);
+				XmlElement elem = node as XmlElement;
+				
+				if (elem == null) 
+					return new XmlNode[] {node};
+				else {
+					XmlNode[] nodes = new XmlNode[elem.Attributes.Count + elem.ChildNodes.Count];
+					int n = 0;
+					foreach (XmlNode no in elem.Attributes)
+						nodes[n++] = no;
+					foreach (XmlNode no in elem.ChildNodes)
+						nodes[n++] = no;
+					return nodes;
+				}
+			}
 
 			if (typeData.Type == typeof (XmlQualifiedName)) return ReadNullableQualifiedName ();
 			return XmlCustomFormatter.FromXmlString (typeData, Reader.ReadElementString ());

+ 3 - 0
mcs/class/System.XML/System.Xml.Serialization/XmlSerializationReaderInterpreter.cs

@@ -17,6 +17,7 @@ namespace System.Xml.Serialization
 	{
 		XmlMapping _typeMap;
 		SerializationFormat _format;
+		static readonly XmlQualifiedName AnyType = new XmlQualifiedName("anyType", System.Xml.Schema.XmlSchema.Namespace);
 
 		public XmlSerializationReaderInterpreter(XmlMapping typeMap)
 		{
@@ -179,6 +180,8 @@ namespace System.Xml.Serialization
 					if (realMap != typeMap)
 						return ReadObject (realMap, false, false);
 				}
+				else if (typeMap.TypeData.Type == typeof(object))
+					return ReadTypedPrimitive (AnyType);
             }
 
 			object ob = Activator.CreateInstance (typeMap.TypeData.Type);