5 // Lluis Sanchez Gual (lluis@ximian.com)
7 // Copyright (C) 2004 Novel Inc.
13 using System
.Collections
;
14 using System
.Web
.Services
.Description
;
16 using System
.Xml
.Schema
;
17 using System
.Xml
.Serialization
;
19 namespace Mono
.WebServices
21 public class ConsoleSampleGenerator
: SampleGenerator
23 public ConsoleSampleGenerator (ServiceDescriptionCollection services
, XmlSchemas schemas
)
24 : base (services
, schemas
)
28 public static void Generate (ArrayList services
, ArrayList schemas
, string binOper
, string protocol
)
30 ServiceDescriptionCollection descCol
= new ServiceDescriptionCollection ();
31 foreach (ServiceDescription sd
in services
)
36 if (schemas
.Count
> 0) {
37 schemaCol
= new XmlSchemas ();
38 foreach (XmlSchema sc
in schemas
)
42 schemaCol
= descCol
[0].Types
.Schemas
;
44 string oper
, bin
= null;
46 int i
= binOper
.IndexOf ('/');
48 oper
= binOper
.Substring (i
+1);
49 bin
= binOper
.Substring (0,i
);
54 ConsoleSampleGenerator sg
= new ConsoleSampleGenerator (descCol
, schemaCol
);
57 sg
.GenerateMessages (oper
, bin
, protocol
, out req
, out resp
);
60 Console
.WriteLine ("Sample request message:");
62 Console
.WriteLine (req
);
64 Console
.WriteLine ("Sample response message:");
66 Console
.WriteLine (resp
);
69 public void GenerateMessages (string operation
, string bindingName
, string protocol
, out string req
, out string resp
)
71 Port port
= FindPort (bindingName
, protocol
);
72 Binding binding
= descriptions
.GetBinding (port
.Binding
);
73 if (binding
== null) throw new InvalidOperationException ("Binding " + bindingName
+ " not found");
75 PortType portType
= descriptions
.GetPortType (binding
.Type
);
76 Operation oper
= FindOperation (portType
, operation
);
77 if (oper
== null) throw new InvalidOperationException ("Operation " + operation
+ " not found");
78 OperationBinding obin
= FindOperation (binding
, operation
);
80 req
= GenerateMessage (port
, obin
, oper
, protocol
, true);
81 resp
= GenerateMessage (port
, obin
, oper
, protocol
, false);
84 Port
FindPort (string portName
, string protocol
)
86 Service service
= descriptions
[0].Services
[0];
87 foreach (Port port
in service
.Ports
)
91 Binding binding
= descriptions
.GetBinding (port
.Binding
);
92 if (GetProtocol (binding
) == protocol
) return port
;
94 else if (port
.Name
== portName
)
100 string GetProtocol (Binding binding
)
102 if (binding
.Extensions
.Find (typeof(SoapBinding
)) != null) return "Soap";
103 HttpBinding hb
= (HttpBinding
) binding
.Extensions
.Find (typeof(HttpBinding
));
104 if (hb
== null) return "";
105 if (hb
.Verb
== "POST") return "HttpPost";
106 if (hb
.Verb
== "GET") return "HttpGet";
110 Operation
FindOperation (PortType portType
, string name
)
112 foreach (Operation oper
in portType
.Operations
) {
113 if (oper
.Messages
.Input
.Name
!= null) {
114 if (oper
.Messages
.Input
.Name
== name
) return oper
;
117 if (oper
.Name
== name
) return oper
;
123 OperationBinding
FindOperation (Binding binding
, string name
)
125 foreach (OperationBinding oper
in binding
.Operations
) {
126 if (oper
.Input
.Name
!= null) {
127 if (oper
.Input
.Name
== name
) return oper
;
130 if (oper
.Name
== name
) return oper
;
138 // Sample generator class
141 public class SampleGenerator
143 protected ServiceDescriptionCollection descriptions
;
144 protected XmlSchemas schemas
;
145 XmlSchemaElement anyElement
;
147 SoapBindingUse currentUse
;
148 XmlDocument document
= new XmlDocument ();
150 static readonly XmlQualifiedName anyType
= new XmlQualifiedName ("anyType",XmlSchema
.Namespace
);
151 static readonly XmlQualifiedName arrayType
= new XmlQualifiedName ("Array","http://schemas.xmlsoap.org/soap/encoding/");
152 static readonly XmlQualifiedName arrayTypeRefName
= new XmlQualifiedName ("arrayType","http://schemas.xmlsoap.org/soap/encoding/");
153 const string SoapEnvelopeNamespace
= "http://schemas.xmlsoap.org/soap/envelope/";
154 const string WsdlNamespace
= "http://schemas.xmlsoap.org/wsdl/";
155 const string SoapEncodingNamespace
= "http://schemas.xmlsoap.org/soap/encoding/";
159 public EncodedType (string ns
, XmlSchemaElement elem
) { Namespace = ns; Element = elem; }
160 public string Namespace
;
161 public XmlSchemaElement Element
;
164 public SampleGenerator (ServiceDescriptionCollection services
, XmlSchemas schemas
)
166 descriptions
= services
;
167 this.schemas
= schemas
;
168 queue
= new ArrayList ();
171 public string GenerateMessage (Port port
, OperationBinding obin
, Operation oper
, string protocol
, bool generateInput
)
173 OperationMessage msg
= null;
174 foreach (OperationMessage opm
in oper
.Messages
)
176 if (opm
is OperationInput
&& generateInput
) msg
= opm
;
177 else if (opm
is OperationOutput
&& !generateInput
) msg
= opm
;
179 if (msg
== null) return null;
182 case "Soap": return GenerateHttpSoapMessage (port
, obin
, oper
, msg
);
183 case "HttpGet": return GenerateHttpGetMessage (port
, obin
, oper
, msg
);
184 case "HttpPost": return GenerateHttpPostMessage (port
, obin
, oper
, msg
);
186 return "Unknown protocol";
189 public string GenerateHttpSoapMessage (Port port
, OperationBinding obin
, Operation oper
, OperationMessage msg
)
193 if (msg
is OperationInput
)
195 SoapAddressBinding sab
= port
.Extensions
.Find (typeof(SoapAddressBinding
)) as SoapAddressBinding
;
196 SoapOperationBinding sob
= obin
.Extensions
.Find (typeof(SoapOperationBinding
)) as SoapOperationBinding
;
197 req
+= "POST " + new Uri (sab
.Location
).AbsolutePath
+ "\n";
198 req
+= "SOAPAction: " + sob
.SoapAction
+ "\n";
199 req
+= "Content-Type: text/xml; charset=utf-8\n";
200 req
+= "Content-Length: " + GetLiteral ("string") + "\n";
201 req
+= "Host: " + GetLiteral ("string") + "\n\n";
205 req
+= "HTTP/1.0 200 OK\n";
206 req
+= "Content-Type: text/xml; charset=utf-8\n";
207 req
+= "Content-Length: " + GetLiteral ("string") + "\n\n";
210 req
+= GenerateSoapMessage (obin
, oper
, msg
);
214 public string GenerateHttpGetMessage (Port port
, OperationBinding obin
, Operation oper
, OperationMessage msg
)
218 if (msg
is OperationInput
)
220 HttpAddressBinding sab
= port
.Extensions
.Find (typeof(HttpAddressBinding
)) as HttpAddressBinding
;
221 HttpOperationBinding sob
= obin
.Extensions
.Find (typeof(HttpOperationBinding
)) as HttpOperationBinding
;
222 string location
= new Uri (sab
.Location
).AbsolutePath
+ sob
.Location
+ "?" + BuildQueryString (msg
);
223 req
+= "GET " + location
+ "\n";
224 req
+= "Host: " + GetLiteral ("string");
228 req
+= "HTTP/1.0 200 OK\n";
229 req
+= "Content-Type: text/xml; charset=utf-8\n";
230 req
+= "Content-Length: " + GetLiteral ("string") + "\n\n";
232 MimeXmlBinding mxb
= (MimeXmlBinding
) obin
.Output
.Extensions
.Find (typeof(MimeXmlBinding
)) as MimeXmlBinding
;
233 if (mxb
== null) return req
;
235 Message message
= descriptions
.GetMessage (msg
.Message
);
236 XmlQualifiedName ename
= null;
237 foreach (MessagePart part
in message
.Parts
)
238 if (part
.Name
== mxb
.Part
) ename
= part
.Element
;
240 if (ename
== null) return req
+ GetLiteral("string");
242 StringWriter sw
= new StringWriter ();
243 XmlTextWriter xtw
= new XmlTextWriter (sw
);
244 xtw
.Formatting
= Formatting
.Indented
;
245 currentUse
= SoapBindingUse
.Literal
;
246 WriteRootElementSample (xtw
, ename
);
248 req
+= sw
.ToString ();
254 public string GenerateHttpPostMessage (Port port
, OperationBinding obin
, Operation oper
, OperationMessage msg
)
258 if (msg
is OperationInput
)
260 HttpAddressBinding sab
= port
.Extensions
.Find (typeof(HttpAddressBinding
)) as HttpAddressBinding
;
261 HttpOperationBinding sob
= obin
.Extensions
.Find (typeof(HttpOperationBinding
)) as HttpOperationBinding
;
262 string location
= new Uri (sab
.Location
).AbsolutePath
+ sob
.Location
;
263 req
+= "POST " + location
+ "\n";
264 req
+= "Content-Type: application/x-www-form-urlencoded\n";
265 req
+= "Content-Length: " + GetLiteral ("string") + "\n";
266 req
+= "Host: " + GetLiteral ("string") + "\n\n";
267 req
+= BuildQueryString (msg
);
269 else return GenerateHttpGetMessage (port
, obin
, oper
, msg
);
274 string BuildQueryString (OperationMessage opm
)
277 Message msg
= descriptions
.GetMessage (opm
.Message
);
278 foreach (MessagePart part
in msg
.Parts
)
280 if (s
.Length
!= 0) s
+= "&";
281 s
+= part
.Name
+ "=" + GetLiteral (part
.Type
.Name
);
286 public string GenerateSoapMessage (OperationBinding obin
, Operation oper
, OperationMessage msg
)
288 SoapOperationBinding sob
= obin
.Extensions
.Find (typeof(SoapOperationBinding
)) as SoapOperationBinding
;
289 SoapBindingStyle style
= (sob
!= null) ? sob
.Style
: SoapBindingStyle
.Document
;
291 MessageBinding msgbin
= (msg
is OperationInput
) ? (MessageBinding
) obin
.Input
: (MessageBinding
)obin
.Output
;
292 SoapBodyBinding sbb
= msgbin
.Extensions
.Find (typeof(SoapBodyBinding
)) as SoapBodyBinding
;
293 SoapBindingUse bodyUse
= (sbb
!= null) ? sbb
.Use
: SoapBindingUse
.Literal
;
295 StringWriter sw
= new StringWriter ();
296 XmlTextWriter xtw
= new XmlTextWriter (sw
);
297 xtw
.Formatting
= Formatting
.Indented
;
299 xtw
.WriteStartDocument ();
300 xtw
.WriteStartElement ("soap", "Envelope", SoapEnvelopeNamespace
);
301 xtw
.WriteAttributeString ("xmlns", "xsi", null, XmlSchema
.InstanceNamespace
);
302 xtw
.WriteAttributeString ("xmlns", "xsd", null, XmlSchema
.Namespace
);
304 if (bodyUse
== SoapBindingUse
.Encoded
)
306 xtw
.WriteAttributeString ("xmlns", "soapenc", null, SoapEncodingNamespace
);
307 xtw
.WriteAttributeString ("xmlns", "tns", null, msg
.Message
.Namespace
);
312 bool writtenHeader
= false;
313 foreach (object ob
in msgbin
.Extensions
)
315 SoapHeaderBinding hb
= ob
as SoapHeaderBinding
;
316 if (hb
== null) continue;
318 if (!writtenHeader
) {
319 xtw
.WriteStartElement ("soap", "Header", SoapEnvelopeNamespace
);
320 writtenHeader
= true;
323 WriteHeader (xtw
, hb
);
327 xtw
.WriteEndElement ();
330 xtw
.WriteStartElement ("soap", "Body", SoapEnvelopeNamespace
);
332 currentUse
= bodyUse
;
333 WriteBody (xtw
, oper
, msg
, sbb
, style
);
335 xtw
.WriteEndElement ();
336 xtw
.WriteEndElement ();
338 return sw
.ToString ();
341 void WriteHeader (XmlTextWriter xtw
, SoapHeaderBinding header
)
343 Message msg
= descriptions
.GetMessage (header
.Message
);
344 if (msg
== null) throw new InvalidOperationException ("Message " + header
.Message
+ " not found");
345 MessagePart part
= msg
.Parts
[header
.Part
];
346 if (part
== null) throw new InvalidOperationException ("Message part " + header
.Part
+ " not found in message " + header
.Message
);
348 currentUse
= header
.Use
;
350 if (currentUse
== SoapBindingUse
.Literal
)
351 WriteRootElementSample (xtw
, part
.Element
);
353 WriteTypeSample (xtw
, part
.Type
);
356 void WriteBody (XmlTextWriter xtw
, Operation oper
, OperationMessage opm
, SoapBodyBinding sbb
, SoapBindingStyle style
)
358 Message msg
= descriptions
.GetMessage (opm
.Message
);
359 if (msg
.Parts
.Count
> 0 && msg
.Parts
[0].Name
== "parameters")
361 MessagePart part
= msg
.Parts
[0];
362 if (part
.Element
== XmlQualifiedName
.Empty
)
363 WriteTypeSample (xtw
, part
.Type
);
365 WriteRootElementSample (xtw
, part
.Element
);
369 string elemName
= oper
.Name
;
371 if (opm
is OperationOutput
) elemName
+= "Response";
373 if (style
== SoapBindingStyle
.Rpc
) {
374 xtw
.WriteStartElement (elemName
, sbb
.Namespace
);
378 foreach (MessagePart part
in msg
.Parts
)
380 if (part
.Element
== XmlQualifiedName
.Empty
)
382 XmlSchemaElement elem
= new XmlSchemaElement ();
383 elem
.SchemaTypeName
= part
.Type
;
384 elem
.Name
= part
.Name
;
385 WriteElementSample (xtw
, ns
, elem
);
388 WriteRootElementSample (xtw
, part
.Element
);
391 if (style
== SoapBindingStyle
.Rpc
)
392 xtw
.WriteEndElement ();
394 WriteQueuedTypeSamples (xtw
);
397 void WriteRootElementSample (XmlTextWriter xtw
, XmlQualifiedName qname
)
399 XmlSchemaElement elem
= (XmlSchemaElement
) schemas
.Find (qname
, typeof(XmlSchemaElement
));
400 if (elem
== null) throw new InvalidOperationException ("Element not found: " + qname
);
401 WriteElementSample (xtw
, qname
.Namespace
, elem
);
404 void WriteElementSample (XmlTextWriter xtw
, string ns
, XmlSchemaElement elem
)
406 XmlQualifiedName root
;
408 if (!elem
.RefName
.IsEmpty
) {
409 XmlSchemaElement refElem
= FindRefElement (elem
);
410 if (refElem
== null) throw new InvalidOperationException ("Global element not found: " + elem
.RefName
);
415 root
= new XmlQualifiedName (elem
.Name
, ns
);
417 if (!elem
.SchemaTypeName
.IsEmpty
)
419 XmlSchemaComplexType st
= FindComplexTyype (elem
.SchemaTypeName
);
421 WriteComplexTypeSample (xtw
, st
, root
);
424 xtw
.WriteStartElement (root
.Name
, root
.Namespace
);
425 if (currentUse
== SoapBindingUse
.Encoded
)
426 xtw
.WriteAttributeString ("type", XmlSchema
.InstanceNamespace
, GetQualifiedNameString (xtw
, elem
.SchemaTypeName
));
427 xtw
.WriteString (GetLiteral (FindBuiltInType (elem
.SchemaTypeName
)));
428 xtw
.WriteEndElement ();
431 else if (elem
.SchemaType
== null)
433 xtw
.WriteStartElement ("any");
434 xtw
.WriteEndElement ();
437 WriteComplexTypeSample (xtw
, (XmlSchemaComplexType
) elem
.SchemaType
, root
);
440 void WriteTypeSample (XmlTextWriter xtw
, XmlQualifiedName qname
)
442 XmlSchemaComplexType ctype
= FindComplexTyype (qname
);
444 WriteComplexTypeSample (xtw
, ctype
, qname
);
448 XmlSchemaSimpleType stype
= (XmlSchemaSimpleType
) schemas
.Find (qname
, typeof(XmlSchemaSimpleType
));
450 WriteSimpleTypeSample (xtw
, stype
);
454 xtw
.WriteString (GetLiteral (FindBuiltInType (qname
)));
455 throw new InvalidOperationException ("Type not found: " + qname
);
458 void WriteComplexTypeSample (XmlTextWriter xtw
, XmlSchemaComplexType stype
, XmlQualifiedName rootName
)
460 WriteComplexTypeSample (xtw
, stype
, rootName
, -1);
463 void WriteComplexTypeSample (XmlTextWriter xtw
, XmlSchemaComplexType stype
, XmlQualifiedName rootName
, int id
)
465 string ns
= rootName
.Namespace
;
467 if (rootName
.Name
.IndexOf ("[]") != -1) rootName
= arrayType
;
469 if (currentUse
== SoapBindingUse
.Encoded
) {
470 string pref
= xtw
.LookupPrefix (rootName
.Namespace
);
471 if (pref
== null) pref
= "q1";
472 xtw
.WriteStartElement (pref
, rootName
.Name
, rootName
.Namespace
);
476 xtw
.WriteStartElement (rootName
.Name
, rootName
.Namespace
);
480 xtw
.WriteAttributeString ("id", "id" + id
);
481 if (rootName
!= arrayType
)
482 xtw
.WriteAttributeString ("type", XmlSchema
.InstanceNamespace
, GetQualifiedNameString (xtw
, rootName
));
485 WriteComplexTypeAttributes (xtw
, stype
);
486 WriteComplexTypeElements (xtw
, ns
, stype
);
488 xtw
.WriteEndElement ();
491 void WriteComplexTypeAttributes (XmlTextWriter xtw
, XmlSchemaComplexType stype
)
493 WriteAttributes (xtw
, stype
.Attributes
, stype
.AnyAttribute
);
496 void WriteComplexTypeElements (XmlTextWriter xtw
, string ns
, XmlSchemaComplexType stype
)
498 if (stype
.Particle
!= null)
499 WriteParticleComplexContent (xtw
, ns
, stype
.Particle
);
502 if (stype
.ContentModel
is XmlSchemaSimpleContent
)
503 WriteSimpleContent (xtw
, (XmlSchemaSimpleContent
)stype
.ContentModel
);
504 else if (stype
.ContentModel
is XmlSchemaComplexContent
)
505 WriteComplexContent (xtw
, ns
, (XmlSchemaComplexContent
)stype
.ContentModel
);
509 void WriteAttributes (XmlTextWriter xtw
, XmlSchemaObjectCollection atts
, XmlSchemaAnyAttribute anyat
)
511 foreach (XmlSchemaObject at
in atts
)
513 if (at
is XmlSchemaAttribute
)
515 XmlSchemaAttribute attr
= (XmlSchemaAttribute
)at
;
516 XmlSchemaAttribute refAttr
= attr
;
518 // refAttr.Form; TODO
520 if (!attr
.RefName
.IsEmpty
) {
521 refAttr
= FindRefAttribute (attr
.RefName
);
522 if (refAttr
== null) throw new InvalidOperationException ("Global attribute not found: " + attr
.RefName
);
526 if (!refAttr
.SchemaTypeName
.IsEmpty
) val
= FindBuiltInType (refAttr
.SchemaTypeName
);
527 else val
= FindBuiltInType ((XmlSchemaSimpleType
) refAttr
.SchemaType
);
529 xtw
.WriteAttributeString (refAttr
.Name
, val
);
531 else if (at
is XmlSchemaAttributeGroupRef
)
533 XmlSchemaAttributeGroupRef gref
= (XmlSchemaAttributeGroupRef
)at
;
534 XmlSchemaAttributeGroup grp
= (XmlSchemaAttributeGroup
) schemas
.Find (gref
.RefName
, typeof(XmlSchemaAttributeGroup
));
535 WriteAttributes (xtw
, grp
.Attributes
, grp
.AnyAttribute
);
540 xtw
.WriteAttributeString ("custom-attribute","value");
543 void WriteParticleComplexContent (XmlTextWriter xtw
, string ns
, XmlSchemaParticle particle
)
545 WriteParticleContent (xtw
, ns
, particle
, false);
548 void WriteParticleContent (XmlTextWriter xtw
, string ns
, XmlSchemaParticle particle
, bool multiValue
)
550 if (particle
is XmlSchemaGroupRef
)
551 particle
= GetRefGroupParticle ((XmlSchemaGroupRef
)particle
);
553 if (particle
.MaxOccurs
> 1) multiValue
= true;
555 if (particle
is XmlSchemaSequence
) {
556 WriteSequenceContent (xtw
, ns
, ((XmlSchemaSequence
)particle
).Items
, multiValue
);
558 else if (particle
is XmlSchemaChoice
) {
559 if (((XmlSchemaChoice
)particle
).Items
.Count
== 1)
560 WriteSequenceContent (xtw
, ns
, ((XmlSchemaChoice
)particle
).Items
, multiValue
);
562 WriteChoiceContent (xtw
, ns
, (XmlSchemaChoice
)particle
, multiValue
);
564 else if (particle
is XmlSchemaAll
) {
565 WriteSequenceContent (xtw
, ns
, ((XmlSchemaAll
)particle
).Items
, multiValue
);
569 void WriteSequenceContent (XmlTextWriter xtw
, string ns
, XmlSchemaObjectCollection items
, bool multiValue
)
571 foreach (XmlSchemaObject item
in items
)
572 WriteContentItem (xtw
, ns
, item
, multiValue
);
575 void WriteContentItem (XmlTextWriter xtw
, string ns
, XmlSchemaObject item
, bool multiValue
)
577 if (item
is XmlSchemaGroupRef
)
578 item
= GetRefGroupParticle ((XmlSchemaGroupRef
)item
);
580 if (item
is XmlSchemaElement
)
582 XmlSchemaElement elem
= (XmlSchemaElement
) item
;
583 XmlSchemaElement refElem
;
584 if (!elem
.RefName
.IsEmpty
) refElem
= FindRefElement (elem
);
587 int num
= (elem
.MaxOccurs
== 1 && !multiValue
) ? 1 : 2;
588 for (int n
=0; n
<num
; n
++)
590 if (currentUse
== SoapBindingUse
.Literal
)
591 WriteElementSample (xtw
, ns
, refElem
);
593 WriteRefTypeSample (xtw
, ns
, refElem
);
596 else if (item
is XmlSchemaAny
)
598 xtw
.WriteString (GetLiteral ("xml"));
600 else if (item
is XmlSchemaParticle
) {
601 WriteParticleContent (xtw
, ns
, (XmlSchemaParticle
)item
, multiValue
);
605 void WriteChoiceContent (XmlTextWriter xtw
, string ns
, XmlSchemaChoice choice
, bool multiValue
)
607 foreach (XmlSchemaObject item
in choice
.Items
)
608 WriteContentItem (xtw
, ns
, item
, multiValue
);
611 void WriteSimpleContent (XmlTextWriter xtw
, XmlSchemaSimpleContent content
)
613 XmlSchemaSimpleContentExtension ext
= content
.Content
as XmlSchemaSimpleContentExtension
;
615 WriteAttributes (xtw
, ext
.Attributes
, ext
.AnyAttribute
);
617 XmlQualifiedName qname
= GetContentBaseType (content
.Content
);
618 xtw
.WriteString (GetLiteral (FindBuiltInType (qname
)));
621 string FindBuiltInType (XmlQualifiedName qname
)
623 if (qname
.Namespace
== XmlSchema
.Namespace
)
626 XmlSchemaComplexType ct
= FindComplexTyype (qname
);
629 XmlSchemaSimpleContent sc
= ct
.ContentModel
as XmlSchemaSimpleContent
;
630 if (sc
== null) throw new InvalidOperationException ("Invalid schema");
631 return FindBuiltInType (GetContentBaseType (sc
.Content
));
634 XmlSchemaSimpleType st
= (XmlSchemaSimpleType
) schemas
.Find (qname
, typeof(XmlSchemaSimpleType
));
636 return FindBuiltInType (st
);
638 throw new InvalidOperationException ("Definition of type " + qname
+ " not found");
641 string FindBuiltInType (XmlSchemaSimpleType st
)
643 if (st
.Content
is XmlSchemaSimpleTypeRestriction
) {
644 return FindBuiltInType (GetContentBaseType (st
.Content
));
646 else if (st
.Content
is XmlSchemaSimpleTypeList
) {
647 string s
= FindBuiltInType (GetContentBaseType (st
.Content
));
648 return s
+ " " + s
+ " ...";
650 else if (st
.Content
is XmlSchemaSimpleTypeUnion
)
652 // Check if all types of the union are equal. If not, then will use anyType.
653 XmlSchemaSimpleTypeUnion uni
= (XmlSchemaSimpleTypeUnion
) st
.Content
;
656 // Anonymous types are unique
657 if (uni
.BaseTypes
.Count
!= 0 && uni
.MemberTypes
.Length
!= 0)
660 foreach (XmlQualifiedName mt
in uni
.MemberTypes
)
662 string qn
= FindBuiltInType (mt
);
663 if (utype
!= null && qn
!= utype
) return "string";
673 XmlQualifiedName
GetContentBaseType (XmlSchemaObject ob
)
675 if (ob
is XmlSchemaSimpleContentExtension
)
676 return ((XmlSchemaSimpleContentExtension
)ob
).BaseTypeName
;
677 else if (ob
is XmlSchemaSimpleContentRestriction
)
678 return ((XmlSchemaSimpleContentRestriction
)ob
).BaseTypeName
;
679 else if (ob
is XmlSchemaSimpleTypeRestriction
)
680 return ((XmlSchemaSimpleTypeRestriction
)ob
).BaseTypeName
;
681 else if (ob
is XmlSchemaSimpleTypeList
)
682 return ((XmlSchemaSimpleTypeList
)ob
).ItemTypeName
;
687 void WriteComplexContent (XmlTextWriter xtw
, string ns
, XmlSchemaComplexContent content
)
689 XmlQualifiedName qname
;
691 XmlSchemaComplexContentExtension ext
= content
.Content
as XmlSchemaComplexContentExtension
;
692 if (ext
!= null) qname
= ext
.BaseTypeName
;
694 XmlSchemaComplexContentRestriction rest
= (XmlSchemaComplexContentRestriction
)content
.Content
;
695 qname
= rest
.BaseTypeName
;
696 if (qname
== arrayType
) {
697 ParseArrayType (rest
, out qname
);
698 XmlSchemaElement elem
= new XmlSchemaElement ();
700 elem
.SchemaTypeName
= qname
;
702 xtw
.WriteAttributeString ("arrayType", SoapEncodingNamespace
, qname
.Name
+ "[2]");
703 WriteContentItem (xtw
, ns
, elem
, true);
708 // Add base map members to this map
709 XmlSchemaComplexType ctype
= FindComplexTyype (qname
);
710 WriteComplexTypeAttributes (xtw
, ctype
);
713 // Add the members of this map
714 WriteAttributes (xtw
, ext
.Attributes
, ext
.AnyAttribute
);
715 if (ext
.Particle
!= null)
716 WriteParticleComplexContent (xtw
, ns
, ext
.Particle
);
719 WriteComplexTypeElements (xtw
, ns
, ctype
);
722 void ParseArrayType (XmlSchemaComplexContentRestriction rest
, out XmlQualifiedName qtype
)
724 XmlSchemaAttribute arrayTypeAt
= FindArrayAttribute (rest
.Attributes
);
725 XmlAttribute
[] uatts
= arrayTypeAt
.UnhandledAttributes
;
726 if (uatts
== null || uatts
.Length
== 0) throw new InvalidOperationException ("arrayType attribute not specified in array declaration");
728 XmlAttribute xat
= null;
729 foreach (XmlAttribute at
in uatts
)
730 if (at
.LocalName
== "arrayType" && at
.NamespaceURI
== WsdlNamespace
)
734 throw new InvalidOperationException ("arrayType attribute not specified in array declaration");
736 string arrayType
= xat
.Value
;
738 int i
= arrayType
.LastIndexOf (":");
739 if (i
== -1) ns
= "";
740 else ns
= arrayType
.Substring (0,i
);
742 int j
= arrayType
.IndexOf ("[", i
+1);
743 if (j
== -1) throw new InvalidOperationException ("Cannot parse WSDL array type: " + arrayType
);
744 type
= arrayType
.Substring (i
+1);
745 type
= type
.Substring (0, type
.Length
-2);
747 qtype
= new XmlQualifiedName (type
, ns
);
750 XmlSchemaAttribute
FindArrayAttribute (XmlSchemaObjectCollection atts
)
752 foreach (object ob
in atts
)
754 XmlSchemaAttribute att
= ob
as XmlSchemaAttribute
;
755 if (att
!= null && att
.RefName
== arrayTypeRefName
) return att
;
757 XmlSchemaAttributeGroupRef gref
= ob
as XmlSchemaAttributeGroupRef
;
760 XmlSchemaAttributeGroup grp
= (XmlSchemaAttributeGroup
) schemas
.Find (gref
.RefName
, typeof(XmlSchemaAttributeGroup
));
761 att
= FindArrayAttribute (grp
.Attributes
);
762 if (att
!= null) return att
;
768 void WriteSimpleTypeSample (XmlTextWriter xtw
, XmlSchemaSimpleType stype
)
770 xtw
.WriteString (GetLiteral (FindBuiltInType (stype
)));
773 XmlSchemaParticle
GetRefGroupParticle (XmlSchemaGroupRef refGroup
)
775 XmlSchemaGroup grp
= (XmlSchemaGroup
) schemas
.Find (refGroup
.RefName
, typeof (XmlSchemaGroup
));
779 XmlSchemaElement
FindRefElement (XmlSchemaElement elem
)
781 if (elem
.RefName
.Namespace
== XmlSchema
.Namespace
)
783 if (anyElement
!= null) return anyElement
;
784 anyElement
= new XmlSchemaElement ();
785 anyElement
.Name
= "any";
786 anyElement
.SchemaTypeName
= anyType
;
789 return (XmlSchemaElement
) schemas
.Find (elem
.RefName
, typeof(XmlSchemaElement
));
792 XmlSchemaAttribute
FindRefAttribute (XmlQualifiedName refName
)
794 if (refName
.Namespace
== XmlSchema
.Namespace
)
796 XmlSchemaAttribute at
= new XmlSchemaAttribute ();
797 at
.Name
= refName
.Name
;
798 at
.SchemaTypeName
= new XmlQualifiedName ("string",XmlSchema
.Namespace
);
801 return (XmlSchemaAttribute
) schemas
.Find (refName
, typeof(XmlSchemaAttribute
));
804 void WriteRefTypeSample (XmlTextWriter xtw
, string ns
, XmlSchemaElement elem
)
806 if (elem
.SchemaTypeName
.Namespace
== XmlSchema
.Namespace
|| schemas
.Find (elem
.SchemaTypeName
, typeof(XmlSchemaSimpleType
)) != null)
807 WriteElementSample (xtw
, ns
, elem
);
810 xtw
.WriteStartElement (elem
.Name
, ns
);
811 xtw
.WriteAttributeString ("href", "#id" + (queue
.Count
+1));
812 xtw
.WriteEndElement ();
813 queue
.Add (new EncodedType (ns
, elem
));
817 void WriteQueuedTypeSamples (XmlTextWriter xtw
)
819 for (int n
=0; n
<queue
.Count
; n
++)
821 EncodedType ec
= (EncodedType
) queue
[n
];
822 XmlSchemaComplexType st
= FindComplexTyype (ec
.Element
.SchemaTypeName
);
823 WriteComplexTypeSample (xtw
, st
, ec
.Element
.SchemaTypeName
, n
+1);
827 XmlSchemaComplexType
FindComplexTyype (XmlQualifiedName qname
)
829 if (qname
.Name
.IndexOf ("[]") != -1)
831 XmlSchemaComplexType stype
= new XmlSchemaComplexType ();
832 stype
.ContentModel
= new XmlSchemaComplexContent ();
834 XmlSchemaComplexContentRestriction res
= new XmlSchemaComplexContentRestriction ();
835 stype
.ContentModel
.Content
= res
;
836 res
.BaseTypeName
= arrayType
;
838 XmlSchemaAttribute att
= new XmlSchemaAttribute ();
839 att
.RefName
= arrayTypeRefName
;
840 res
.Attributes
.Add (att
);
842 XmlAttribute xat
= document
.CreateAttribute ("arrayType", WsdlNamespace
);
843 xat
.Value
= qname
.Namespace
+ ":" + qname
.Name
;
844 att
.UnhandledAttributes
= new XmlAttribute
[] {xat}
;
848 return (XmlSchemaComplexType
) schemas
.Find (qname
, typeof(XmlSchemaComplexType
));
851 string GetQualifiedNameString (XmlTextWriter xtw
, XmlQualifiedName qname
)
853 string pref
= xtw
.LookupPrefix (qname
.Namespace
);
854 if (pref
!= null) return pref
+ ":" + qname
.Name
;
856 xtw
.WriteAttributeString ("xmlns", "q1", null, qname
.Namespace
);
857 return "q1:" + qname
.Name
;
860 protected virtual string GetLiteral (string s
)