2 // XmlFormatterSerializer.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2005 Novell, Inc. http://www.novell.com
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Collections;
32 using System.Reflection;
33 using System.Runtime.Serialization.Formatters.Binary;
35 using System.Xml.Schema;
37 using QName = System.Xml.XmlQualifiedName;
39 namespace System.Runtime.Serialization
41 internal class XmlFormatterSerializer
43 XmlDictionaryWriter writer;
45 KnownTypeCollection types;
49 IDataContractSurrogate surrogate;
52 ArrayList objects = new ArrayList ();
53 Hashtable references = new Hashtable (); // preserve possibly referenced objects to ids. (new in 3.5 SP1)
55 public static void Serialize (XmlDictionaryWriter writer, object graph,
56 KnownTypeCollection types,
57 bool ignoreUnknown, int maxItems, string root_ns)
59 new XmlFormatterSerializer (writer, types, ignoreUnknown, maxItems, root_ns)
60 .Serialize (graph != null ? graph.GetType () : null, graph);
63 public XmlFormatterSerializer (XmlDictionaryWriter writer,
64 KnownTypeCollection types,
65 bool ignoreUnknown, int maxItems, string root_ns)
69 ignore_unknown = ignoreUnknown;
73 public ArrayList SerializingObjects {
74 get { return objects; }
77 public IDictionary References {
78 get { return references; }
81 public XmlDictionaryWriter Writer {
82 get { return writer; }
85 public void Serialize (Type type, object graph)
88 writer.WriteAttributeString ("nil", XmlSchema.InstanceNamespace, "true");
90 Type actualType = graph.GetType ();
92 SerializationMap map = types.FindUserMap (actualType);
94 /* Unknown actual type */
95 types.Add (actualType);
96 map = types.FindUserMap (actualType);
99 if (actualType != type && (map == null || map.OutputXsiType)) {
100 QName qname = types.GetXmlName (actualType);
101 string name = qname.Name;
102 string ns = qname.Namespace;
103 if (qname == QName.Empty) {
104 name = XmlConvert.EncodeLocalName (actualType.Name);
105 ns = KnownTypeCollection.DefaultClrNamespaceBase + actualType.Namespace;
106 } else if (qname.Namespace == KnownTypeCollection.MSSimpleNamespace)
107 ns = XmlSchema.Namespace;
108 if (writer.LookupPrefix (ns) == null) // it goes first (extraneous, but it makes att order compatible)
109 writer.WriteXmlnsAttribute (null, ns);
110 writer.WriteStartAttribute ("type", XmlSchema.InstanceNamespace);
111 writer.WriteQualifiedName (name, ns);
112 writer.WriteEndAttribute ();
114 QName predef = KnownTypeCollection.GetPredefinedTypeName (actualType);
115 if (predef != QName.Empty)
116 SerializePrimitive (type, graph, predef);
118 map.Serialize (graph, this);
122 public void SerializePrimitive (Type type, object graph, QName qname)
124 // writer.WriteStartAttribute ("type", XmlSchema.InstanceNamespace);
125 // writer.WriteQualifiedName (qname.Name, qname.Namespace);
126 // writer.WriteEndAttribute ();
127 writer.WriteString (KnownTypeCollection.PredefinedTypeObjectToString (graph));
130 public void WriteStartElement (string rootName, string rootNamespace, string currentNamespace)
132 writer.WriteStartElement (rootName, rootNamespace);
133 if (!string.IsNullOrEmpty (currentNamespace) && currentNamespace != rootNamespace)
134 writer.WriteXmlnsAttribute (null, currentNamespace);
137 public void WriteEndElement ()
139 writer.WriteEndElement ();