This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mcs / class / System.XML / System.Xml.Serialization / XmlTypeMapping.cs
1 //\r
2 // XmlTypeMapping.cs: \r
3 //\r
4 // Author:\r
5 //   John Donagher (john@webmeta.com)\r
6 //   Lluis Sanchez Gual (lluis@ximian.com)\r
7 //\r
8 // (C) 2002 John Donagher\r
9 //\r
10
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31 \r
32 using System.Xml;\r
33 using System;\r
34 using System.Collections;\r
35 using System.Globalization;\r
36 \r
37 namespace System.Xml.Serialization\r
38 {\r
39         public class XmlTypeMapping : XmlMapping\r
40         {\r
41                 private string elementName;\r
42                 private string ns;\r
43                 private string xmlType;\r
44                 private string xmlTypeNamespace;\r
45                 TypeData type;\r
46                 XmlTypeMapping baseMap;\r
47                 bool multiReferenceType = false;\r
48                 bool isSimpleType;\r
49                 string documentation;\r
50                 bool includeInSchema;\r
51                 bool isNullable = true;\r
52 \r
53                 ArrayList _derivedTypes = new ArrayList();\r
54 \r
55                 internal XmlTypeMapping(string elementName, string ns, TypeData typeData, string xmlType, string xmlTypeNamespace)\r
56                 {\r
57                         this.elementName = elementName;\r
58                         this.ns = ns;\r
59                         this.type = typeData;\r
60                         this.xmlType = xmlType;\r
61                         this.xmlTypeNamespace = xmlTypeNamespace;\r
62                 }\r
63 \r
64                 public string ElementName\r
65                 {\r
66                         get { return elementName; }\r
67                 }\r
68 \r
69                 public string Namespace\r
70                 {\r
71                         get { return ns; }\r
72                 }\r
73 \r
74                 public string TypeFullName\r
75                 {\r
76                         get { return type.FullTypeName; }\r
77                 }\r
78 \r
79                 public string TypeName\r
80                 {\r
81                         get { return type.TypeName; }\r
82                 }\r
83 \r
84                 internal TypeData TypeData\r
85                 {\r
86                         get { return type; }\r
87                 }\r
88 \r
89                 internal string XmlType\r
90                 {\r
91                         get { return xmlType; }\r
92                 }\r
93 \r
94                 internal string XmlTypeNamespace\r
95                 {\r
96                         get { return xmlTypeNamespace; }\r
97                 }\r
98 \r
99                 internal ArrayList DerivedTypes\r
100                 {\r
101                         get { return _derivedTypes; }\r
102                         set { _derivedTypes = value; }\r
103                 }\r
104 \r
105                 internal bool MultiReferenceType\r
106                 {\r
107                         get { return multiReferenceType; }\r
108                         set { multiReferenceType = value; }\r
109                 }\r
110 \r
111                 internal XmlTypeMapping BaseMap\r
112                 {\r
113                         get { return baseMap; }\r
114                         set { baseMap = value; }\r
115                 }\r
116 \r
117                 internal bool IsSimpleType\r
118                 {\r
119                         get { return isSimpleType; }\r
120                         set { isSimpleType = value; }\r
121                 }\r
122 \r
123                 internal string Documentation\r
124                 {\r
125                         set { documentation = value; }\r
126                         get { return documentation; }\r
127                 }\r
128 \r
129                 internal bool IncludeInSchema\r
130                 {\r
131                         get { return includeInSchema; }\r
132                         set { includeInSchema = value; }\r
133                 }\r
134                 \r
135                 internal bool IsNullable\r
136                 {\r
137                         get { return isNullable; }\r
138                         set { isNullable = value; }\r
139                 }\r
140 \r
141                 internal XmlTypeMapping GetRealTypeMap (string objectFullTypeName)\r
142                 {\r
143                         // Returns the map for a subtype of this map's type\r
144 \r
145                         objectFullTypeName = objectFullTypeName.Replace ('+','.');\r
146                         if (TypeFullName == objectFullTypeName) return this;\r
147                         for (int n=0; n<_derivedTypes.Count; n++) {\r
148                                 XmlTypeMapping map = (XmlTypeMapping) _derivedTypes[n];\r
149                                 if (map.TypeFullName == objectFullTypeName) return map;\r
150                         }\r
151                         \r
152                         return null;\r
153                 }\r
154 \r
155                 internal XmlTypeMapping GetRealElementMap (string name, string ens)\r
156                 {\r
157                         if (xmlType == name && xmlTypeNamespace == ens) return this;\r
158                         foreach (XmlTypeMapping map in _derivedTypes)\r
159                                 if (map.xmlType == name && map.xmlTypeNamespace == ens) return map;\r
160                         \r
161                         return null;\r
162                 }\r
163                 \r
164                 internal void UpdateRoot (XmlQualifiedName qname)\r
165                 {\r
166                         if (qname != null) {\r
167                                 this.elementName = qname.Name;\r
168                                 this.ns = qname.Namespace;\r
169                         }\r
170                 }\r
171         }\r
172 \r
173         // Mapping info for classes and structs\r
174 \r
175         internal class ClassMap: ObjectMap\r
176         {\r
177                 Hashtable _elements = new Hashtable ();\r
178                 ArrayList _elementMembers;\r
179                 Hashtable _attributeMembers;\r
180                 XmlTypeMapMemberAttribute[] _attributeMembersArray;\r
181                 XmlTypeMapElementInfo[] _elementsByIndex;\r
182                 ArrayList _flatLists;\r
183                 ArrayList _allMembers = new ArrayList ();\r
184                 ArrayList _membersWithDefault;\r
185                 XmlTypeMapMemberAnyElement _defaultAnyElement;\r
186                 XmlTypeMapMemberAnyAttribute _defaultAnyAttribute;\r
187                 XmlTypeMapMemberNamespaces _namespaceDeclarations;\r
188                 XmlTypeMapMember _xmlTextCollector;\r
189                 XmlTypeMapMember _returnMember;\r
190                 bool _ignoreMemberNamespace;\r
191                 bool _canBeSimpleType = true;\r
192 \r
193                 public void AddMember (XmlTypeMapMember member)\r
194                 {\r
195                         _allMembers.Add (member);\r
196                         \r
197                         if (!(member.DefaultValue is System.DBNull)) {\r
198                                 if (_membersWithDefault == null) _membersWithDefault = new ArrayList ();\r
199                                 _membersWithDefault.Add (member);\r
200                         }\r
201                         \r
202                         if (member.IsReturnValue)\r
203                                 _returnMember = member;\r
204                         \r
205                         if (member is XmlTypeMapMemberAttribute)\r
206                         {\r
207                                 XmlTypeMapMemberAttribute atm = (XmlTypeMapMemberAttribute)member;\r
208                                 if (_attributeMembers == null) _attributeMembers = new Hashtable();\r
209                                 string key = BuildKey (atm.AttributeName, atm.Namespace);\r
210                                 if (_attributeMembers.ContainsKey (key))\r
211                                         throw new InvalidOperationException ("The XML attribute named '" + atm.AttributeName + "' from namespace '" + atm.Namespace + "' already present in the current scope. Use XML attributes to specify another XML name or namespace for the attribute.");\r
212                                 member.Index = _attributeMembers.Count;\r
213                                 _attributeMembers.Add (key, member);\r
214                                 return;\r
215                         }\r
216                         else if (member is XmlTypeMapMemberFlatList)\r
217                         {\r
218                                 RegisterFlatList ((XmlTypeMapMemberFlatList)member);\r
219                         }\r
220                         else if (member is XmlTypeMapMemberAnyElement)\r
221                         {\r
222                                 XmlTypeMapMemberAnyElement mem = (XmlTypeMapMemberAnyElement) member;\r
223                                 if (mem.IsDefaultAny) _defaultAnyElement = mem;\r
224                                 if (mem.TypeData.IsListType) RegisterFlatList (mem);\r
225                         }\r
226                         else if (member is XmlTypeMapMemberAnyAttribute)\r
227                         {\r
228                                 _defaultAnyAttribute = (XmlTypeMapMemberAnyAttribute) member;\r
229                                 return;\r
230                         }\r
231                         else if (member is XmlTypeMapMemberNamespaces)\r
232                         {\r
233                                 _namespaceDeclarations = (XmlTypeMapMemberNamespaces) member;\r
234                                 return;\r
235                         }\r
236 \r
237                         if (member is XmlTypeMapMemberElement && ((XmlTypeMapMemberElement)member).IsXmlTextCollector)\r
238                         {\r
239                                 if (_xmlTextCollector != null) throw new InvalidOperationException ("XmlTextAttribute can only be applied once in a class");\r
240                                 _xmlTextCollector = member;\r
241                         }\r
242 \r
243                         if (_elementMembers == null) {\r
244                                 _elementMembers = new ArrayList();\r
245                                 _elements = new Hashtable();\r
246                         }\r
247 \r
248                         member.Index = _elementMembers.Count;\r
249                         _elementMembers.Add (member);\r
250 \r
251                         ICollection elemsInfo = ((XmlTypeMapMemberElement)member).ElementInfo;\r
252                         foreach (XmlTypeMapElementInfo elem in elemsInfo)\r
253                         {\r
254                                 string key = BuildKey (elem.ElementName, elem.Namespace);\r
255                                 if (_elements.ContainsKey (key)) \r
256                                         throw new InvalidOperationException ("The XML element named '" + elem.ElementName + "' from namespace '" + elem.Namespace + "' already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.");\r
257                                 _elements.Add (key, elem);\r
258                         }\r
259                 }\r
260 \r
261                 void RegisterFlatList (XmlTypeMapMemberExpandable member)\r
262                 {\r
263                         if (_flatLists == null) _flatLists = new ArrayList ();\r
264                         member.FlatArrayIndex = _flatLists.Count;\r
265                         _flatLists.Add (member);\r
266                 }\r
267 \r
268                 public XmlTypeMapMemberAttribute GetAttribute (string name, string ns)\r
269                 {\r
270                         if (_attributeMembers == null) return null;\r
271                         return (XmlTypeMapMemberAttribute)_attributeMembers [BuildKey(name,ns)];\r
272                 }\r
273 \r
274                 public XmlTypeMapElementInfo GetElement (string name, string ns)\r
275                 {\r
276                         if (_elements == null) return null;\r
277                         return (XmlTypeMapElementInfo)_elements [BuildKey(name,ns)];\r
278                 }\r
279                 \r
280                 public XmlTypeMapElementInfo GetElement (int index)\r
281                 {\r
282                         if (_elements == null) return null;\r
283                         \r
284                         if (_elementsByIndex == null)\r
285                         {\r
286                                 _elementsByIndex = new XmlTypeMapElementInfo [_elementMembers.Count];\r
287                                 foreach (XmlTypeMapMemberElement mem in _elementMembers)\r
288                                 {\r
289                                         if (mem.ElementInfo.Count != 1) \r
290                                                 throw new InvalidOperationException ("Read by order only possible for encoded/bare format");\r
291                                                 \r
292                                         _elementsByIndex [mem.Index] = (XmlTypeMapElementInfo) mem.ElementInfo [0];\r
293                                 }\r
294                         }\r
295                         \r
296                         return _elementsByIndex [index];\r
297                 }\r
298                 \r
299                 private string BuildKey (string name, string ns)\r
300                 {\r
301                         if (_ignoreMemberNamespace) return name;\r
302                         else return name + " / " + ns;\r
303                 }\r
304                 \r
305                 public ICollection AllElementInfos\r
306                 {\r
307                         get { return _elements.Values; }\r
308                 }\r
309                 \r
310                 \r
311                 public bool IgnoreMemberNamespace\r
312                 {\r
313                         get { return _ignoreMemberNamespace; }\r
314                         set { _ignoreMemberNamespace = value; }\r
315                 }\r
316 \r
317                 public XmlTypeMapMember FindMember (string name)\r
318                 {\r
319                         for (int n=0; n<_allMembers.Count; n++)\r
320                                 if (((XmlTypeMapMember)_allMembers[n]).Name == name) return (XmlTypeMapMember)_allMembers[n];\r
321                         return null;\r
322                 }\r
323 \r
324                 public XmlTypeMapMemberAnyElement DefaultAnyElementMember\r
325                 {\r
326                         get { return _defaultAnyElement; }\r
327                 }\r
328 \r
329                 public XmlTypeMapMemberAnyAttribute DefaultAnyAttributeMember\r
330                 {\r
331                         get { return _defaultAnyAttribute; }\r
332                 }\r
333 \r
334                 public XmlTypeMapMemberNamespaces NamespaceDeclarations\r
335                 {\r
336                         get { return _namespaceDeclarations; }\r
337                 }\r
338 \r
339                 public ICollection AttributeMembers\r
340                 {\r
341                         get \r
342                         {\r
343                                 if (_attributeMembers == null) return null;\r
344                                 if (_attributeMembersArray != null) return _attributeMembersArray;\r
345                                 \r
346                                 _attributeMembersArray = new XmlTypeMapMemberAttribute[_attributeMembers.Count];\r
347                                 foreach (XmlTypeMapMemberAttribute mem in _attributeMembers.Values)\r
348                                         _attributeMembersArray [mem.Index] = mem;\r
349                                 return _attributeMembersArray;\r
350                         }\r
351                 }\r
352 \r
353                 public ICollection ElementMembers\r
354                 {\r
355                         get { return _elementMembers; }\r
356                 }\r
357 \r
358                 public ArrayList AllMembers\r
359                 {\r
360                         get { return _allMembers; }\r
361                 }\r
362 \r
363                 public ArrayList FlatLists\r
364                 {\r
365                         get { return _flatLists; }\r
366                 }\r
367                 \r
368                 public ArrayList MembersWithDefault\r
369                 {\r
370                         get { return _membersWithDefault; }\r
371                 }\r
372 \r
373                 public XmlTypeMapMember XmlTextCollector\r
374                 {\r
375                         get { return _xmlTextCollector; }\r
376                 }\r
377                 \r
378                 public XmlTypeMapMember ReturnMember\r
379                 {\r
380                         get { return _returnMember; }\r
381                 }\r
382 \r
383                 public XmlQualifiedName SimpleContentBaseType\r
384                 {\r
385                         get\r
386                         {\r
387                                 if (!_canBeSimpleType || _elementMembers == null || _elementMembers.Count != 1) return null;\r
388                                 XmlTypeMapMemberElement member = (XmlTypeMapMemberElement) _elementMembers[0];\r
389                                 if (member.ElementInfo.Count != 1) return null;\r
390                                 XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) member.ElementInfo[0];\r
391                                 if (!einfo.IsTextElement) return null;\r
392                                 if (member.TypeData.SchemaType == SchemaTypes.Primitive || member.TypeData.SchemaType == SchemaTypes.Enum)\r
393                                         return new XmlQualifiedName (einfo.TypeData.XmlType, einfo.DataTypeNamespace);\r
394                                 return null;\r
395                         }\r
396                 }\r
397                 \r
398                 public void SetCanBeSimpleType (bool can)\r
399                 {\r
400                         _canBeSimpleType = can;\r
401                 }\r
402 \r
403                 public bool HasSimpleContent\r
404                 {\r
405                         get\r
406                         {\r
407                                 return SimpleContentBaseType != null;\r
408                         }\r
409                 }\r
410 \r
411         }\r
412 \r
413         // Mapping info for arrays and lists\r
414 \r
415         internal class ListMap: ObjectMap\r
416         {\r
417                 XmlTypeMapElementInfoList _itemInfo;\r
418                 bool _gotNestedMapping;\r
419                 XmlTypeMapping _nestedArrayMapping;\r
420 \r
421                 public bool IsMultiArray\r
422                 {\r
423                         get\r
424                         {\r
425                                 return (NestedArrayMapping != null);\r
426                         }\r
427                 }\r
428 \r
429                 public XmlTypeMapping NestedArrayMapping\r
430                 {\r
431                         get\r
432                         {\r
433                                 if (_gotNestedMapping) return _nestedArrayMapping;\r
434                                 _gotNestedMapping = true;\r
435 \r
436                                 _nestedArrayMapping = ((XmlTypeMapElementInfo)_itemInfo[0]).MappedType;\r
437 \r
438                                 if (_nestedArrayMapping == null) return null;\r
439                                 \r
440                                 if (_nestedArrayMapping.TypeData.SchemaType != SchemaTypes.Array) {\r
441                                         _nestedArrayMapping = null; return null;\r
442                                 }\r
443 \r
444                                 foreach (XmlTypeMapElementInfo elem in _itemInfo)\r
445                                         if (elem.MappedType != _nestedArrayMapping) {\r
446                                                 _nestedArrayMapping = null;\r
447                                                 return null;\r
448                                         }\r
449 \r
450                                 return _nestedArrayMapping;\r
451                         }\r
452                 }\r
453 \r
454                 public XmlTypeMapElementInfoList ItemInfo\r
455                 {\r
456 \r
457                         get { return _itemInfo; }\r
458                         set { _itemInfo = value; }\r
459                 }\r
460 \r
461                 public XmlTypeMapElementInfo FindElement (object memberValue)\r
462                 {\r
463                         if (_itemInfo.Count == 1) \r
464                                 return (XmlTypeMapElementInfo) _itemInfo[0];\r
465                         else\r
466                         {\r
467                                 if (memberValue == null) return null;\r
468                                 Type type = memberValue.GetType();\r
469                                 foreach (XmlTypeMapElementInfo elem in _itemInfo)\r
470                                         if (elem.TypeData.Type == type) return elem;\r
471                         }\r
472                         return null;\r
473                 }       \r
474 \r
475                 public XmlTypeMapElementInfo FindElement (string elementName, string ns)\r
476                 {\r
477                         foreach (XmlTypeMapElementInfo elem in _itemInfo)\r
478                                 if (elem.ElementName == elementName && elem.Namespace == ns) return elem;\r
479                         return null;\r
480                 }\r
481                 \r
482                 public XmlTypeMapElementInfo FindTextElement ()\r
483                 {\r
484                         foreach (XmlTypeMapElementInfo elem in _itemInfo)\r
485                                 if (elem.IsTextElement) return elem;\r
486                         return null;\r
487                 }\r
488                 \r
489                 public string GetSchemaArrayName ()\r
490                 {\r
491                         XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) _itemInfo[0];\r
492                         if (einfo.MappedType != null) return TypeTranslator.GetArrayName (einfo.MappedType.XmlType);\r
493                         else return TypeTranslator.GetArrayName (einfo.TypeData.XmlType);\r
494                 }\r
495 \r
496                 public void GetArrayType (int itemCount, out string localName, out string ns)\r
497                 {\r
498                         string arrayDim;\r
499                         if (itemCount != -1) arrayDim = "[" + itemCount + "]";\r
500                         else arrayDim = "[]";\r
501 \r
502                         XmlTypeMapElementInfo info = (XmlTypeMapElementInfo) _itemInfo[0];\r
503                         if (info.TypeData.SchemaType == SchemaTypes.Array)\r
504                         {\r
505                                 string nm;\r
506                                 ((ListMap)info.MappedType.ObjectMap).GetArrayType (-1, out nm, out ns);\r
507                                 localName = nm + arrayDim;\r
508                         }\r
509                         else \r
510                         {\r
511                                 if (info.MappedType != null)\r
512                                 {\r
513                                         localName = info.MappedType.XmlType + arrayDim;\r
514                                         ns = info.MappedType.Namespace;\r
515                                 }\r
516                                 else \r
517                                 {\r
518                                         localName = info.TypeData.XmlType + arrayDim;\r
519                                         ns = info.DataTypeNamespace;\r
520                                 }\r
521                         }\r
522                 }\r
523 \r
524                 public override bool Equals (object other)\r
525                 {\r
526                         ListMap lmap = other as ListMap;\r
527                         if (lmap == null) return false;\r
528 \r
529                         if (_itemInfo.Count != lmap._itemInfo.Count) return false;\r
530                         for (int n=0; n<_itemInfo.Count; n++)\r
531                                 if (!_itemInfo[n].Equals (lmap._itemInfo[n])) return false;\r
532                         return true;\r
533                 }\r
534 \r
535                 public override int GetHashCode ()\r
536                 {\r
537                         return base.GetHashCode ();\r
538                 }\r
539         }\r
540 \r
541         internal class EnumMap: ObjectMap\r
542         {\r
543                 EnumMapMember[] _members;\r
544                 bool _isFlags;\r
545 \r
546                 public class EnumMapMember\r
547                 {\r
548                         string _xmlName;\r
549                         string _enumName;\r
550                         string _documentation;\r
551 \r
552                         public EnumMapMember (string xmlName, string enumName)\r
553                         {\r
554                                 _xmlName = xmlName;\r
555                                 _enumName = enumName;\r
556                         }\r
557 \r
558                         public string XmlName\r
559                         {\r
560                                 get { return _xmlName; }\r
561                         }\r
562 \r
563                         public string EnumName\r
564                         {\r
565                                 get { return _enumName; }\r
566                         }\r
567 \r
568                         public string Documentation\r
569                         {\r
570                                 get { return _documentation; }\r
571                                 set { _documentation = value; }\r
572                         }\r
573                 }\r
574 \r
575                 public EnumMap (EnumMapMember[] members, bool isFlags)\r
576                 {\r
577                         _members = members;\r
578                         _isFlags = isFlags;\r
579                 }\r
580                 \r
581                 public bool IsFlags\r
582                 {\r
583                         get { return _isFlags; }\r
584                 }\r
585 \r
586                 public EnumMapMember[] Members\r
587                 {\r
588                         get { return _members; }\r
589                 }\r
590 \r
591                 public string GetXmlName (object enumValue)\r
592                 {\r
593                         string enumName = enumValue.ToString();\r
594 \r
595                         if (_isFlags && enumName.IndexOf (',') != -1)\r
596                         {\r
597                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();\r
598                                 string[] enumNames = enumValue.ToString().Split (',');\r
599                                 foreach (string name in enumNames)\r
600                                 {\r
601                                         string tname = name.Trim();\r
602                                         foreach (EnumMapMember mem in _members)\r
603                                                 if (mem.EnumName == tname) {\r
604                                                         sb.Append (mem.XmlName).Append (' ');\r
605                                                         break;\r
606                                                 }\r
607                                 }\r
608                                 sb.Remove (sb.Length-1, 1);\r
609                                 return sb.ToString ();\r
610                         }\r
611 \r
612                         foreach (EnumMapMember mem in _members)\r
613                                 if (mem.EnumName == enumName) return mem.XmlName;\r
614                         \r
615                         return Convert.ToInt64(enumValue).ToString(CultureInfo.InvariantCulture);\r
616                 }\r
617 \r
618                 public string GetEnumName (string xmlName)\r
619                 {\r
620                         if (_isFlags && xmlName.Length == 0) \r
621                                 return "0";\r
622                         \r
623                         if (_isFlags && xmlName.Trim().IndexOf (' ') != -1)\r
624                         {\r
625                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();\r
626                                 string[] enumNames = xmlName.ToString().Split (' ');\r
627                                 foreach (string name in enumNames)\r
628                                 {\r
629                                         if (name == string.Empty) continue;\r
630                                         string foundEnumValue = null;\r
631                                         foreach (EnumMapMember mem in _members)\r
632                                                 if (mem.XmlName == name) { foundEnumValue = mem.EnumName; break; }\r
633 \r
634                                         if (foundEnumValue != null) sb.Append (foundEnumValue).Append (','); \r
635                                         else return null;\r
636                                 }\r
637                                 sb.Remove (sb.Length-1, 1);\r
638                                 return sb.ToString ();\r
639                         }\r
640 \r
641                         foreach (EnumMapMember mem in _members)\r
642                                 if (mem.XmlName == xmlName) return mem.EnumName;\r
643                                 \r
644                         return null;\r
645                 }\r
646         }\r
647 }\r