Click here to Skip to main content
15,881,248 members
Articles / Programming Languages / C#

UDDI Explorer: Tool for Searching Web Services

Rate me:
Please Sign up or sign in to vote.
4.93/5 (49 votes)
20 Dec 200517 min read 221.6K   3.2K   109  
Tool for searching web service(s) and viewing their WSDL information
//Author contact: Thanh.Dao@gmx.net

using System;
using System.Collections;
using System.Reflection;
using System.Threading;
using System.Web.Services.Description;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace Kofax.WFD.UI.SchemaHelper
{
	#region Denote Prefix for long schem name
	//Denote prefix for long name data type
	//Simply later by I2
	using QName = XmlQualifiedName; 
	using Form = XmlSchemaForm; 
	using Use = XmlSchemaUse; 
	using SOM=XmlSchema;
	using SOMList = XmlSchemaObjectCollection; 
	using SOMObject = XmlSchemaObject; 
	using Element = XmlSchemaElement; 
	using Attr = XmlSchemaAttribute; 
	using AttrGroup = XmlSchemaAttributeGroup; 
	using AttrGroupRef = XmlSchemaAttributeGroupRef; 
	using SimpleType = XmlSchemaSimpleType; 
	using ComplexType = XmlSchemaComplexType; 
	using SimpleModel = XmlSchemaSimpleContent; 
	using SimpleExt = XmlSchemaSimpleContentExtension; 
	using SimpleRst = XmlSchemaSimpleContentRestriction; 
	using ComplexModel = XmlSchemaComplexContent; 
	using ComplexExt = XmlSchemaComplexContentExtension; 
	using ComplexRst = XmlSchemaComplexContentRestriction; 
	using SimpleTypeRst = XmlSchemaSimpleTypeRestriction; 
	using SimpleTypeModel = XmlSchemaSimpleTypeContent;
	using SimpleList = XmlSchemaSimpleTypeList; 
	using SimpleUnion = XmlSchemaSimpleTypeUnion; 
	using SchemaFacet = XmlSchemaFacet; 
	using EnumerationFacet = XmlSchemaEnumerationFacet; 
	using MinExcludesiveFacet=XmlSchemaMinExclusiveFacet ;
	using LengthFacet = XmlSchemaLengthFacet; 
	using MinLengthFacet = XmlSchemaMinLengthFacet; 
	using PatternFacet = XmlSchemaPatternFacet;
	using Particle = XmlSchemaParticle; 
	using Sequence = XmlSchemaSequence; 
	using Choice = XmlSchemaChoice;
	using Annotation=XmlSchemaAnnotation;
	using Documentation=XmlSchemaDocumentation;
	using AnyAttribute=XmlSchemaAnyAttribute;
	using AnyElement=XmlSchemaAny;
	using GroupRef=XmlSchemaGroupRef;
	using Group=XmlSchemaGroup;
	using All=XmlSchemaAll ;
	using Include=XmlSchemaInclude;
	#endregion

	/// <summary>
	/// Summary description for SchemaParser.
	/// </summary>	
	
	public class SchemaParser
	{					
		public class NodeData
		{
			public XmlQualifiedName Name;
			public string Type;
			public string Namespace;
			public bool Qualified;
            public string Description = string.Empty;
			public XmlSchemaObject baseObj;
			public bool MultiValue=false;
			public bool Nullable=false;
			public string Value=string.Empty;
			public string ObjectType=string.Empty;

			public NodeData (XmlSchemaObject obj, XmlQualifiedName name, string type, string desc, string defaultValue) 
			{   
				baseObj=obj; 
				Name=name; 
				Type=type; 
				Namespace=name.Namespace;
                Description=desc;
				ObjectType=obj.GetType().ToString() ;
			}

		}			

		XmlSchemas _schemas;
		public static int TimeOver=2000;

		private static readonly XmlQualifiedName arrayType=new XmlQualifiedName ("Array","http://schemas.xmlsoap.org/soap/encoding/");
		private static readonly XmlQualifiedName arrayTypeRefName=new XmlQualifiedName ("arrayType","http://schemas.xmlsoap.org/soap/encoding/");

		XmlSchemaElement _anyElement;
		public SoapBindingUse BindingUse=SoapBindingUse.Literal;		
		ArrayList _queue;
		

		class Encoded
		{
			public string Namespace;
			public XmlSchemaElement Element;
			public Encoded (string ns, XmlSchemaElement elem) 
			{ Namespace=ns; Element=elem; }
		}

		void MyInit()
		{			
			_anyElement=new XmlSchemaElement ();
			_anyElement.Name="any";
			_anyElement.SchemaTypeName=new XmlQualifiedName ("anyType",XmlSchema.Namespace);
			_queue=new ArrayList ();
			 
		}
		
		public SchemaParser (XmlSchemas schemas)
		{
			MyInit ();
			this._schemas=schemas;			
			Do_PrefixTagging();
		}
		
		public TreeNode Translate (XmlQualifiedName qname)
		{
			processHasExited=false;
			_node=new TreeNode() ;
            _node.ImageIndex = 17;
            _node.SelectedImageIndex = 17;
			_qname=qname;
			_lookupType=null;
			StartParsing();

			//Run_Thread ()

			return _node;
		}

		public TreeNode Translate (XmlQualifiedName qname, XmlSchemaObject obj)
		{
			processHasExited=false;
			_node=new TreeNode() ;
			_node.ImageIndex = 17;
			_node.SelectedImageIndex = 17;
			_qname=qname;
			_lookupType=obj.GetType();
		
			StartParsing();
			//Run_Thread ()
			
			return _node;
		}
		
		void Run_Thread()
		{
			ThreadStart threadStart = new ThreadStart(StartParsing);
			Thread thread = new Thread(threadStart);

			thread.Start();

			thread.Join(TimeOver);

		}

		XmlSerializerNamespaces _namespaces=new XmlSerializerNamespaces() ;

		void Do_PrefixTagging()
		{
			_namespaces=new XmlSerializerNamespaces();
			for(int i=0; i < _schemas.Count; i++)
			{						
				XmlSchema schema=_schemas[i];
				
				if (schema.TargetNamespace != string.Empty && NamespaceHandler.LoopupPrefix(_namespaces, schema.TargetNamespace) == string.Empty)
				{
					_namespaces.Add("m" + i, schema.TargetNamespace) ;
				}

			}

			for(int i=0; i < _schemas.Count; i++)
			{
				XmlSchema schema=_schemas[i];
				XmlQualifiedName[] XmlQualifiedNameList=schema.Namespaces.ToArray();					
									
				XmlSerializerNamespaces xmlns=new XmlSerializerNamespaces() ;	

				int j=0;
				foreach (XmlQualifiedName qname in XmlQualifiedNameList )
				{
					//if (XmlQualifiedName.Name == string.Empty )
					{
						++j;
						if (qname.Namespace == schema.TargetNamespace)
						{
							string prefix=NamespaceHandler.LoopupPrefix(_namespaces, schema.TargetNamespace);

							if (prefix != string.Empty)
							{
								xmlns.Add(prefix, qname.Namespace) ;
							}
							else
							{
								xmlns.Add("tns", qname.Namespace) ;
							}
						}
						else
						{
							string prefix=NamespaceHandler.LoopupPrefix(_namespaces, schema.TargetNamespace);

							if (prefix != string.Empty)
							{
								xmlns.Add(prefix, qname.Namespace) ;
							}
							else
							{
								xmlns.Add("ns"+j, qname.Namespace) ;
							}
						}
					}
								
				}
				schema.Namespaces = xmlns ;
			}
		}

		XmlQualifiedName _qname;
		TreeNode _node;
		Type _lookupType;
		bool processHasExited=false;

		void StartParsing()
		{
			try
			{					
				processHasExited=false;

				object lookup=null;
				if (_lookupType == null)									
					lookup=_schemas.Find(_qname, typeof(XmlSchemaElement)) ;				
				else				
					lookup=_schemas.Find(_qname, _lookupType) ;					
				
				if (lookup is XmlSchemaElement)
					Create_RootElement (_node, _qname);	
				else
					Create_CustomType (_node, _qname);

				processHasExited=true;
			}
			catch(Exception e)
			{
				throw e;				
			}			
		}
				
		
		void Create_RootElement (TreeNode inner, XmlQualifiedName qname)
		{
			XmlSchemaElement elem=(XmlSchemaElement) _schemas.Find (qname, typeof(XmlSchemaElement));
			if (elem == null) throw new Exception ("Element not found: " + qname);
			Add_Element (inner, qname.Namespace, elem);
		}

        string GetAnnotation(Annotation annot)
        {
            if (annot == null) return "";
            string annotation=string.Empty;            
         
			foreach (XmlSchemaObject obj in annot.Items )
			{
				XmlSchemaDocumentation doc=obj as XmlSchemaDocumentation ;
				XmlSchemaAppInfo app=obj as XmlSchemaAppInfo ;
				if (doc != null)
					annotation +=GetDocumentContent( doc.Markup) ;

				if (app != null)
					annotation +=GetDocumentContent( app.Markup)  ;

			}
            return annotation;
        }

        string GetDocumentContent(XmlNode[] nodes)
        {
            string strContent = "";
            foreach (XmlNode node in nodes)
            {
                strContent = strContent + node.InnerText.Trim() + Environment.NewLine;
            }
            return strContent;
        }

		bool IsInfiniteRecursiveLoop(TreeNode parent, XmlQualifiedName qname)
		{
			if (qname.IsEmpty) return false;

			TreeNode ancestor=parent;
			int count=0;
			while (ancestor != null)
			{				
				if (ancestor.Tag != null && ancestor.Tag is NodeData) 
				{
					XmlQualifiedName aqname=((NodeData) ancestor.Tag).Name ;
					if (aqname.Equals(qname)  )					
						++count;					
				}
				ancestor=ancestor.Parent;
			}

			return count > 1;
		}

		XmlSchema GetSchemaByName(string targetNamespace)
		{
			for(int i=0; i < _schemas.Count; i++)
				if (_schemas[i].TargetNamespace == targetNamespace)
				{						
					return _schemas[i];					
				}
			return null;
		}

		
		void Add_Element (TreeNode complexNode, string ns, XmlSchemaElement elem)
		{
			//add to complexNode
			XmlQualifiedName nodeName=XmlQualifiedName.Empty;
				
			if (!elem.RefName.IsEmpty) 
			{
				XmlSchemaElement refElem=GetRefElement (elem);
				if (refElem == null) throw new Exception ("Global element not found: " + elem.RefName);
				nodeName=elem.RefName;
				elem=refElem;

			}
			else
			{				
				nodeName=elem.QualifiedName;
			}
			
			if (IsInfiniteRecursiveLoop (complexNode, nodeName)) return;

			TreeNode elemNode=new TreeNode(nodeName.Name) ;
            elemNode.ImageIndex=1;
            elemNode.SelectedImageIndex = 1;

			if (nodeName.Namespace != string.Empty)
			{
				elemNode.Text=NamespaceHandler.LoopupPrefix(_namespaces, nodeName.Namespace ) + ":" + nodeName.Name ;
			}			
			
			elemNode.Tag=nodeName;
			complexNode.Nodes.Add(elemNode) ;
            string desc = GetAnnotation(elem.Annotation);
			
			
			NodeData data=new NodeData(elem, nodeName, "", desc, elem.DefaultValue) ;				
			elemNode.Tag=data;

			if (!elem.SchemaTypeName.IsEmpty)
			{
				XmlSchemaComplexType ct=GetComplexTypeByName (elem.SchemaTypeName);
				

				if (ct != null)
				{
					data.Type=ct.QualifiedName.Name;

					Parse_ComplexType (elemNode, ct, nodeName);						
				}
				else
					if (!elem.SchemaTypeName.IsEmpty)
				{																		
					data.Type=GetBuiltInTypeName (elem.SchemaTypeName);
					string test="";
					if (BindingUse == SoapBindingUse.Encoded) 
						 test="type"  + GetQualifiedNameString (complexNode, elem.SchemaTypeName)
							+( (GetBuiltInTypeName (elem.SchemaTypeName)));						
				}
			}
			else if (elem.SchemaType == null)
			{
				data.Type="any";
			}
			else
			{
				if (elem.SchemaType is XmlSchemaComplexType) 
					Parse_ComplexType (elemNode, (XmlSchemaComplexType) elem.SchemaType, nodeName);
				else
					if (elem.SchemaType is XmlSchemaSimpleType)
					{
						XmlSchemaSimpleType st=elem.SchemaType as XmlSchemaSimpleType;
						data.Type=GetBuiltInTypeName (st.QualifiedName );						
					}
			}


			
		}
		
		void Create_CustomType (TreeNode inner, XmlQualifiedName qname)
		{
			XmlSchemaComplexType ctype=GetComplexTypeByName (qname);
			TreeNode node=new TreeNode() ;			
			inner.Nodes.Add(node) ;
			node.Text=qname.Name;

			if (ctype != null) 
			{
                node.ImageIndex = 3;
                node.SelectedImageIndex = 3;

				Parse_ComplexType (node, ctype, qname);
				return;
			}
				
			XmlSchemaSimpleType stype=(XmlSchemaSimpleType) _schemas.Find (qname, typeof(XmlSchemaSimpleType));
			if (stype != null) 
			{
                node.ImageIndex = 2;
                node.SelectedImageIndex = 2;

				Parse_SimpleType (node, stype);
				return;
			}
			
			inner.Tag=((GetBuiltInTypeName (qname)));

			throw new Exception ("Type not found: " + qname);
		}
		
		void Parse_ComplexType (TreeNode inner, XmlSchemaComplexType stype, XmlQualifiedName rootName)
		{			
			Parse_ComplexType (inner, stype, rootName, -1);
		}
		
		void Parse_ComplexType (TreeNode innerNode, XmlSchemaComplexType stype, XmlQualifiedName rootName, int id)
		{
			string ns=rootName.Namespace;

			
			if (rootName.Name.IndexOf ("[]") != -1) rootName=arrayType;
			
			if (BindingUse == SoapBindingUse.Encoded) 
			{
				innerNode.Text=NamespaceHandler.LoopupPrefix(_namespaces, rootName.Namespace ) + ":" + rootName.Name ;
				//innerNode.Text = rootName.Namespace + ":" + rootName.Name;
				ns=string.Empty;
			}
			else
			{	
				if (rootName.Namespace != string.Empty)
					innerNode.Text=NamespaceHandler.LoopupPrefix(_namespaces, rootName.Namespace ) + ":" + rootName.Name ;
				else
					innerNode.Text=rootName.Name;
			}
		
			if (innerNode.Tag == null)
			{
                string desc = GetAnnotation(stype.Annotation);
				NodeData data=new NodeData(stype, rootName, "", desc , string.Empty) ;
				innerNode.Tag=data;
			}
			
			if (id != -1)
			{

				TreeNode node=new TreeNode("id:" + id) ;
				innerNode.Nodes.Add(node) ;

				if (rootName != arrayType)
				{
					TreeNode node2=new TreeNode("Type" + GetQualifiedNameString (innerNode, rootName)) ;
					node.Nodes.Add(node2) ;
				}
			}
			
			Add_ComplexAttributes (innerNode, stype);
			Add_ComplexElements (innerNode, ns, stype);			
		}
		
		void Add_ComplexAttributes (TreeNode inner, XmlSchemaComplexType stype)
		{
			Add_Attributes (inner, stype.Attributes, stype.AnyAttribute);
		}
		
		void Add_ComplexElements (TreeNode complexNode, string ns, XmlSchemaComplexType stype)
		{

			if (stype.Particle != null)
			{
				Parse_ParticleComplexContent (complexNode, ns, stype.Particle);
			}
			else
			{
				if (stype.ContentModel is XmlSchemaSimpleContent)
					Parse_SimpleContent (complexNode, (XmlSchemaSimpleContent)stype.ContentModel);
				else if (stype.ContentModel is XmlSchemaComplexContent)
					Parse_ComplexContent (complexNode, ns, (XmlSchemaComplexContent)stype.ContentModel);
			}
		}

		void Add_Attributes (TreeNode innerNode, XmlSchemaObjectCollection atts, XmlSchemaAnyAttribute anyat)
		{
			foreach (XmlSchemaObject at in atts)
			{
				if (at is XmlSchemaAttribute)
				{						
					XmlSchemaAttribute attr=(XmlSchemaAttribute)at;
					XmlSchemaAttribute refAttr=attr;											
					
					if (!attr.RefName.IsEmpty) 
					{
						refAttr=GetRefAttribute (attr.RefName);
						if (refAttr == null) throw new Exception ("Global attribute not found: " + attr.RefName);
					}
					
					string type;
					if (!refAttr.SchemaTypeName.IsEmpty) type=GetBuiltInTypeName (refAttr.SchemaTypeName);
					else type=GetBuiltInType (refAttr.SchemaType);
		            
			        
					TreeNode node=new TreeNode(refAttr.Name) ;
                    node.ImageIndex = 4;
                    node.SelectedImageIndex = 4;
                    string desc = GetAnnotation(refAttr.Annotation);
					if (refAttr.QualifiedName.Namespace != string.Empty)
					{
						node.Text=NamespaceHandler.LoopupPrefix(_namespaces, refAttr.QualifiedName.Namespace ) + ":" + refAttr.Name ;
					}			

					NodeData data=new NodeData(at, refAttr.QualifiedName, type, desc, refAttr.DefaultValue) ;
					node.Tag=data;

					innerNode.Nodes.Add(node) ;						
						
				}
				else if (at is XmlSchemaAttributeGroupRef)
				{
					XmlSchemaAttributeGroupRef gref=(XmlSchemaAttributeGroupRef)at;
					XmlSchemaAttributeGroup grp=(XmlSchemaAttributeGroup) _schemas.Find (gref.RefName, typeof(XmlSchemaAttributeGroup));
					Add_Attributes (innerNode, grp.Attributes, grp.AnyAttribute);
				}
			}
			
			if (anyat != null)
			{
				TreeNode node=new TreeNode("any custom-attribute") ;
				innerNode.Nodes.Add(node) ;				
			}
		}
		
		void Parse_ParticleComplexContent (TreeNode complexNode, string ns, XmlSchemaParticle particle)
		{
			Parse_ParticleContent (complexNode, ns, particle, false);
		}
		
		void Parse_ParticleContent (TreeNode complexNode, string ns, XmlSchemaParticle particle, bool multiValue)
		{
			if (particle is XmlSchemaGroupRef)
				particle=GetRefGroupParticle ((XmlSchemaGroupRef)particle);

			if (particle.MaxOccurs > 1) multiValue=true;
			
			if (particle is XmlSchemaSequence) 
			{
				Parse_SequenceContent (complexNode, ns, ((XmlSchemaSequence)particle).Items, multiValue);
			}
			else if (particle is XmlSchemaChoice) 
			{
				if (((XmlSchemaChoice)particle).Items.Count == 1)
					Parse_SequenceContent (complexNode, ns, ((XmlSchemaChoice)particle).Items, multiValue);
				else
					Parse_ChoiceContent (complexNode, ns, (XmlSchemaChoice)particle, multiValue);
			}
			else if (particle is XmlSchemaAll) 
			{
				Parse_SequenceContent (complexNode, ns, ((XmlSchemaAll)particle).Items, multiValue);
			}
		}

		void Parse_SequenceContent (TreeNode complexNode, string ns, XmlSchemaObjectCollection items, bool multiValue)
		{
			foreach (XmlSchemaObject item in items)
				Add_Item (complexNode, ns, item, multiValue);
		}
		
		void Add_Item (TreeNode complexNode, string ns, XmlSchemaObject item, bool multiValue)
		{
			if (item is XmlSchemaGroupRef)
				item=GetRefGroupParticle ((XmlSchemaGroupRef)item);
					
			if (item is XmlSchemaElement)
			{
				XmlSchemaElement elem=(XmlSchemaElement) item;
				XmlSchemaElement refElem;
				if (!elem.RefName.IsEmpty) refElem=GetRefElement (elem);
				else refElem=elem;

				int num=(elem.MaxOccurs == 1 && !multiValue) ? 1 : 2;

				for (int n=0; n<num; n++)
				{
					if (BindingUse == SoapBindingUse.Literal)
						Add_Element (complexNode, ns, refElem);
					else
						Add_RefType (complexNode, ns, refElem);
				}
			}
			else if (item is XmlSchemaAny)
			{
				TreeNode node=new TreeNode( ("xml")) ;
				complexNode.Nodes.Add(node) ;					
			}
			else if (item is XmlSchemaParticle) 
			{
				Parse_ParticleContent (complexNode, ns, (XmlSchemaParticle)item, multiValue);
			}
		}
		
		void Parse_ChoiceContent (TreeNode inner, string ns, XmlSchemaChoice choice, bool multiValue)
		{
			foreach (XmlSchemaObject item in choice.Items)
				Add_Item (inner, ns, item, multiValue);
		}

		void Parse_SimpleContent (TreeNode inner, XmlSchemaSimpleContent content)
		{
			XmlSchemaSimpleContentExtension ext=content.Content as XmlSchemaSimpleContentExtension;
			XmlSchemaSimpleContentRestriction rst=content.Content as XmlSchemaSimpleContentRestriction;

			if (ext != null)
				Add_Attributes (inner, ext.Attributes, ext.AnyAttribute);
			else
				if (rst != null)
					Add_Attributes (inner, rst.Attributes, rst.AnyAttribute);
			
			XmlQualifiedName qname=GetContentBaseType (content.Content);
			TreeNode node=new TreeNode( (GetBuiltInTypeName (qname))) ;
			inner.Nodes.Add(node) ;				
		}

		string GetBuiltInTypeName (XmlQualifiedName qname)
		{
			if (qname.IsEmpty)
			{
				return "";
			}

			if (qname.Namespace == XmlSchema.Namespace)
				return qname.Name;

			XmlSchemaComplexType ct=GetComplexTypeByName (qname);
			if (ct != null)
			{
				XmlSchemaSimpleContent sc=ct.ContentModel as XmlSchemaSimpleContent;
				if (sc == null) throw new Exception ("Invalid schema");
				return GetBuiltInTypeName (GetContentBaseType (sc.Content));
			}
			
			XmlSchemaSimpleType st=(XmlSchemaSimpleType) _schemas.Find (qname, typeof(XmlSchemaSimpleType));
			if (st != null)
				return GetBuiltInType (st);

			throw new Exception ("Definition of type " + qname + " not found");
		}

		string GetBuiltInType (XmlSchemaSimpleType st)
		{
			if (st == null) return string.Empty ;

			if (st.Content is XmlSchemaSimpleTypeRestriction) 
			{
				return GetBuiltInTypeName (GetContentBaseType (st.Content));
			}
			else if (st.Content is XmlSchemaSimpleTypeList) 
			{
				string s=GetBuiltInTypeName (GetContentBaseType (st.Content));
				return s + " " + s + " ...";// fun but i dont care this kind of types
			}
			else if (st.Content is XmlSchemaSimpleTypeUnion)
			{
				
				XmlSchemaSimpleTypeUnion uni=(XmlSchemaSimpleTypeUnion) st.Content;
				string utype=null;


				if (uni.BaseTypes.Count != 0 && uni.MemberTypes.Length != 0)
					return "string";

				foreach (XmlQualifiedName mt in uni.MemberTypes)
				{
					string qn=GetBuiltInTypeName (mt);
					if (utype != null && qn != utype) return "string";
					else utype=qn;
				}
				return utype;
			}
			else
				return "string";
		}
		

		XmlQualifiedName GetContentBaseType (XmlSchemaObject obj)
		{
			if (obj is XmlSchemaSimpleContentExtension)
				return ((XmlSchemaSimpleContentExtension)obj).BaseTypeName;
			else if (obj is XmlSchemaSimpleContentRestriction)
				return ((XmlSchemaSimpleContentRestriction)obj).BaseTypeName;
			else if (obj is XmlSchemaSimpleTypeRestriction)
				return ((XmlSchemaSimpleTypeRestriction)obj).BaseTypeName;
			else if (obj is XmlSchemaSimpleTypeList)
				return ((XmlSchemaSimpleTypeList)obj).ItemTypeName;
			else
				return null;
		}
		
		const string WsdlNamespace="http://schemas.xmlsoap.org/wsdl/";
		const string SoapEncodingNamespace="http://schemas.xmlsoap.org/soap/encoding/";

		void Parse_ComplexContent (TreeNode inner, string ns, XmlSchemaComplexContent content)
		{
			XmlQualifiedName qname;

			XmlSchemaComplexContentExtension ext=content.Content as XmlSchemaComplexContentExtension;
			if (ext != null) qname=ext.BaseTypeName;
			else 
			{
				XmlSchemaComplexContentRestriction rest=(XmlSchemaComplexContentRestriction)content.Content;
				qname=rest.BaseTypeName;
				
				Add_Attributes (inner, rest.Attributes, rest.AnyAttribute);

				if (qname == arrayType) 
				{
					Parse_ArrayType (rest, out qname);
					XmlSchemaElement elem=new XmlSchemaElement ();
					elem.Name="Item";
					elem.SchemaTypeName=qname;
					
					TreeNode node=new TreeNode("arrayType" + SoapEncodingNamespace + qname.Name + "[2]") ;
					inner.Nodes.Add(node) ;
					Add_Item (inner, ns, elem, true);
					return;
				}
				else
					if (rest.Particle != null)
				{
					//?? Parse rest particle content	?					
					Parse_ParticleComplexContent(inner, ns, rest.Particle);
				}

				return;
			}
			
			
			XmlSchemaComplexType cbase=GetComplexTypeByName (qname);

			if (cbase != null)
			{
				Add_ComplexAttributes (inner, cbase);
				//Add base content first
				Add_ComplexElements (inner, ns, cbase);
			}
			
			if (ext != null) 
			{
				// Add the members of this map
				Add_Attributes (inner, ext.Attributes, ext.AnyAttribute);
				if (ext.Particle != null)
					Parse_ParticleComplexContent (inner, ns, ext.Particle);
			}
			
			
		}
		
		void Parse_ArrayType (XmlSchemaComplexContentRestriction rest, out XmlQualifiedName qtype)
		{
			XmlSchemaAttribute arrayTypeAt=GetArrayAttribute (rest.Attributes);
			XmlAttribute[] uatts=arrayTypeAt.UnhandledAttributes;
			if (uatts == null || uatts.Length == 0) throw new Exception ("arrayType attribute not specified in array declaration");
			
			XmlAttribute xat=null;
			foreach (XmlAttribute at in uatts)
				if (at.LocalName == "arrayType" && at.NamespaceURI == WsdlNamespace)
				{ xat=at; break; }
			
			if (xat == null) 
				throw new Exception ("arrayType attribute not specified in array declaration");
			
			string arrayType=xat.Value;
			string type, ns;
			int i=arrayType.LastIndexOf (":");
			if (i == -1) ns=string.Empty;
			else ns=arrayType.Substring (0,i);
			
			int j=arrayType.IndexOf ("[", i+1);
			if (j == -1) throw new Exception ("Cannot parse WSDL array type: " + arrayType);
			type=arrayType.Substring (i+1);
			type=type.Substring (0, type.Length-2);
			
			qtype=new XmlQualifiedName (type, ns);
		}
		
		XmlSchemaAttribute GetArrayAttribute (XmlSchemaObjectCollection atts)
		{
			foreach (object ob in atts)
			{
				XmlSchemaAttribute att=ob as XmlSchemaAttribute;
				if (att != null && att.RefName == arrayTypeRefName) return att;
				
				XmlSchemaAttributeGroupRef gref=ob as XmlSchemaAttributeGroupRef;
				if (gref != null)
				{
					XmlSchemaAttributeGroup grp=(XmlSchemaAttributeGroup) _schemas.Find (gref.RefName, typeof(XmlSchemaAttributeGroup));
					att=GetArrayAttribute (grp.Attributes);
					if (att != null) return att;
				}
			}
			return null;
		
		}

		void Add_Facet(TreeNode simpleNode, XmlSchemaFacet facet)
		{						
			TreeNode node=new TreeNode(facet.Value) ;
			simpleNode.Nodes.Add(node) ;

		}
		
		void Parse_AnyObject(TreeNode inner, XmlSchemaObject obj)
		{						
			XmlSchemaFacet facet=obj as XmlSchemaFacet;
			XmlSchemaAttribute attrib=obj as XmlSchemaAttribute;

			if (facet != null) 
				Add_Facet(inner, facet);		
			
			Type type=obj.GetType();
			PropertyInfo[] properties=type.GetProperties ();			

			foreach (PropertyInfo property in properties)
			{
				if (property.PropertyType.FullName.Equals(typeof(XmlSchemaObjectCollection).ToString()))
				{
					XmlSchemaObjectCollection somList=property.GetValue(obj, null) as XmlSchemaObjectCollection;

					if (somList != null)
						foreach (XmlSchemaObject somObj in somList) 
						{
							Parse_AnyObject (inner, somObj);
						}
				}				
			}	

		}

		void Parse_SimpleType (TreeNode inner, XmlSchemaSimpleType stype)
		{
			if (inner.Text == string.Empty)
				inner.Text= (GetBuiltInType (stype));

			if (stype.Content != null)			
				Parse_AnyObject (inner, stype.Content);
			

			if (inner.Tag == null)
			{
                string desc=GetAnnotation(stype.Annotation);
				NodeData data=new NodeData(stype, stype.QualifiedName, string.Empty, desc, string.Empty) ;
				inner.Tag=data;
			}
			
		}
		
		XmlSchemaParticle GetRefGroupParticle (XmlSchemaGroupRef refGroup)
		{
			XmlSchemaGroup grp=(XmlSchemaGroup) _schemas.Find (refGroup.RefName, typeof (XmlSchemaGroup));
			return grp.Particle;
		}

		XmlSchemaElement GetRefElement (XmlSchemaElement elem)
		{
			if (elem.RefName.Namespace == XmlSchema.Namespace)
			{
				if (_anyElement != null) return _anyElement;
				return _anyElement;
			}
			return (XmlSchemaElement) _schemas.Find (elem.RefName, typeof(XmlSchemaElement));
		}
		

		
		XmlSchemaAttribute GetRefAttribute (XmlQualifiedName refName)
		{
			if (refName.Namespace == XmlSchema.Namespace)
			{
				XmlSchemaAttribute at=new XmlSchemaAttribute ();
				at.Name=refName.Name;
				at.SchemaTypeName=new XmlQualifiedName ("string",XmlSchema.Namespace);
				return at;
			}
			return (XmlSchemaAttribute) _schemas.Find (refName, typeof(XmlSchemaAttribute));
		}
		
		void Add_RefType (TreeNode inner, string ns, XmlSchemaElement elem)
		{
			if (elem.SchemaTypeName.Namespace == XmlSchema.Namespace || _schemas.Find (elem.SchemaTypeName, typeof(XmlSchemaSimpleType)) != null)
				Add_Element (inner, ns, elem);
			else
			{
				TreeNode node=new TreeNode(elem.Name + ns) ;
				TreeNode node2=new TreeNode("href" + "#id" + (_queue.Count+1)) ;
				node.Nodes.Add(node2) ;
				inner.Nodes.Add(node) ;				
				_queue.Add (new Encoded (ns, elem));
			}
		}
		
		void Parse_QueuedType (TreeNode inner)
		{
			for (int n=0; n<_queue.Count; n++)
			{
				Encoded ec=(Encoded) _queue[n];
				XmlSchemaComplexType st=GetComplexTypeByName (ec.Element.SchemaTypeName);
				Parse_ComplexType (inner, st, ec.Element.SchemaTypeName, n+1);
			}
		}
		
		XmlSchemaComplexType GetComplexTypeByName (XmlQualifiedName qname)
		{
			if (qname.Name.IndexOf ("[]") != -1)
			{
				XmlSchemaComplexType stype=new XmlSchemaComplexType ();
				stype.ContentModel=new XmlSchemaComplexContent ();
				
				XmlSchemaComplexContentRestriction res=new XmlSchemaComplexContentRestriction ();
				stype.ContentModel.Content=res;
				res.BaseTypeName=arrayType;
				
				XmlSchemaAttribute att=new XmlSchemaAttribute ();
				att.RefName=arrayTypeRefName;
				res.Attributes.Add (att);
									
					
				return stype;
			}
				
			return (XmlSchemaComplexType) _schemas.Find (qname, typeof(XmlSchemaComplexType));
		}
		
		string GetQualifiedNameString (TreeNode inner, XmlQualifiedName qname)
		{
			TreeNode node=new TreeNode("xmlns q1=" + qname.Namespace);
			return "q1:" + qname.Name;
		}
				
	}
	
	
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.


Written By
Software Developer
Vietnam Vietnam
I'm still alive...but temporarily moved to work on mobile & web stuffs(j2me/brew/php/flash...something not M$). things have just been very busy, and probably will continue...so don't have chance to maintain & respond. Hope will have time to try to write again, because many ideas with WPF &silver light are waiting. wish me luck Smile | :)

FYI:
- MESHSimPack project(c# library for measuring similarity among concepts of the MESH ontology):
http://sourceforge.net/projects/meshsimpack.

Comments and Discussions