⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlschemacompletiondata.cs

📁 c#源代码
💻 CS
📖 第 1 页 / 共 3 页
字号:
//
// SharpDevelop Xml Editor
//
// Copyright (C) 2005 Matthew Ward
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// Matthew Ward (mrward@users.sourceforge.net)

using ICSharpCode.TextEditor.Gui.CompletionWindow;
using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Schema;

namespace ICSharpCode.XmlEditor
{
	/// <summary>
	/// Holds the completion (intellisense) data for an xml schema.
	/// </summary>
	/// <remarks>
	/// The XmlSchema class throws an exception if we attempt to load 
	/// the xhtml1-strict.xsd schema.  It does not like the fact that
	/// this schema redefines the xml namespace, even though this is
	/// allowed by the w3.org specification.
	/// </remarks>
	public class XmlSchemaCompletionData
	{
		string namespaceUri = String.Empty;
		XmlSchema schema;
		string fileName = String.Empty;
		bool readOnly = false;
		
		/// <summary>
		/// Stores attributes that have been prohibited whilst the code
		/// generates the attribute completion data.
		/// </summary>
		XmlSchemaObjectCollection prohibitedAttributes = new XmlSchemaObjectCollection();
		
		public XmlSchemaCompletionData()
		{
		}
		
		/// <summary>
		/// Creates completion data from the schema passed in 
		/// via the reader object.
		/// </summary>
		public XmlSchemaCompletionData(TextReader reader)
		{
			ReadSchema(String.Empty, reader);
		}
		
		/// <summary>
		/// Creates completion data from the schema passed in 
		/// via the reader object.
		/// </summary>
		public XmlSchemaCompletionData(XmlTextReader reader)
		{
			reader.XmlResolver = null;
			ReadSchema(reader);
		}
		
		/// <summary>
		/// Creates the completion data from the specified schema file.
		/// </summary>
		public XmlSchemaCompletionData(string fileName) : this(String.Empty, fileName)
		{
		}
		
		/// <summary>
		/// Creates the completion data from the specified schema file and uses
		/// the specified baseUri to resolve any referenced schemas.
		/// </summary>
		public XmlSchemaCompletionData(string baseUri, string fileName)
		{
			StreamReader reader = new StreamReader(fileName, true);
			ReadSchema(baseUri, reader);
			this.fileName = fileName;
		}		
		
		/// <summary>
		/// Gets the schema.
		/// </summary>
		public XmlSchema Schema {
			get {
				return schema;
			}
		}
		
		/// <summary>
		/// Read only schemas are those that are installed with 
		/// SharpDevelop.
		/// </summary>
		public bool ReadOnly {
			get {
				return readOnly;
			}
			
			set {
				readOnly = value;
			}
		}
		
		/// <summary>
		/// Gets or sets the schema's file name.
		/// </summary>
		public string FileName {
			get {
				return fileName;
			}
			set {
				fileName = value;
			}
		}
		
		/// <summary>
		/// Gets the namespace URI for the schema.
		/// </summary>
		public string NamespaceUri {
			get {
				return namespaceUri;
			}
		}
		
		/// <summary>
		/// Converts the filename into a valid Uri.
		/// </summary>
		public static string GetUri(string fileName)
		{
			string uri = String.Empty;
			
			if (fileName != null) {
				if (fileName.Length > 0) {
					uri = String.Concat("file:///", fileName.Replace('\\', '/'));
				}
			}
			
			return uri;
		}

		/// <summary>
		/// Gets the possible root elements for an xml document using this schema.
		/// </summary>
		public ICompletionData[] GetElementCompletionData()
		{
			return GetElementCompletionData(String.Empty);
		}
		
		/// <summary>
		/// Gets the possible root elements for an xml document using this schema.
		/// </summary>
		public ICompletionData[] GetElementCompletionData(string namespacePrefix)
		{
			XmlCompletionDataCollection data = new XmlCompletionDataCollection();
			
			foreach (XmlSchemaElement element in schema.Elements.Values) {
				if (element.Name != null) {
					AddElement(data, element.Name, namespacePrefix, element.Annotation);
				} else {
					// Do not add reference element.
				}
			}
			
			return data.ToArray();
		}
		
		/// <summary>
		/// Gets the attribute completion data for the xml element that exists
		/// at the end of the specified path.
		/// </summary>
		public ICompletionData[] GetAttributeCompletionData(XmlElementPath path)
		{
			XmlCompletionDataCollection data = new XmlCompletionDataCollection();
					
			// Locate matching element.
			XmlSchemaElement element = FindElement(path);
			
			// Get completion data.
			if (element != null) {
				prohibitedAttributes.Clear();
				data = GetAttributeCompletionData(element);
			}
			
			return data.ToArray();
		}
		
		/// <summary>
		/// Gets the child element completion data for the xml element that exists
		/// at the end of the specified path.
		/// </summary>
		public ICompletionData[] GetChildElementCompletionData(XmlElementPath path)
		{
			XmlCompletionDataCollection data = new XmlCompletionDataCollection();
		
			// Locate matching element.
			XmlSchemaElement element = FindElement(path);
			
			// Get completion data.
			if (element != null) {
				data = GetChildElementCompletionData(element, path.Elements.LastPrefix);
			}
			
			return data.ToArray();
		}		
		
		/// <summary>
		/// Gets the autocomplete data for the specified attribute value.
		/// </summary>
		public ICompletionData[] GetAttributeValueCompletionData(XmlElementPath path, string name)
		{
			XmlCompletionDataCollection data = new XmlCompletionDataCollection();
			
			// Locate matching element.
			XmlSchemaElement element = FindElement(path);
			
			// Get completion data.
			if (element != null) {
				data = GetAttributeValueCompletionData(element, name);
			}
			
			return data.ToArray();
		}
		
		/// <summary>
		/// Handler for schema validation errors.
		/// </summary>
		void SchemaValidation(object source, ValidationEventArgs e)
		{
			// Do nothing.
		}
		
		/// <summary>
		/// Loads the schema.
		/// </summary>
		void ReadSchema(XmlReader reader)
		{
			try
			{
				schema = XmlSchema.Read(reader, new ValidationEventHandler(SchemaValidation));
				schema.Compile(new ValidationEventHandler(SchemaValidation));
			
				namespaceUri = schema.TargetNamespace;
			}
			finally
			{
				reader.Close();
			}
		}
		
		void ReadSchema(string baseUri, TextReader reader)
		{
			XmlTextReader xmlReader = new XmlTextReader(baseUri, reader);
			
			// Setting the resolver to null allows us to
			// load the xhtml1-strict.xsd without any exceptions if
			// the referenced dtds exist in the same folder as the .xsd
			// file.  If this is not set to null the dtd files are looked
			// for in the assembly's folder.
			xmlReader.XmlResolver = null;
			ReadSchema(xmlReader);
		}			
		
		/// <summary>
		/// Finds an element in the schema.
		/// </summary>
		/// <remarks>
		/// Only looks at the elements that are defined in the 
		/// root of the schema so it will not find any elements
		/// that are defined inside any complex types.
		/// </remarks>
		XmlSchemaElement FindElement(QualifiedName name)
		{
			XmlSchemaElement matchedElement = null;
			foreach (XmlSchemaElement element in schema.Elements.Values) {
				if (name.Equals(element.QualifiedName)) {
					matchedElement = element;
					break;
				}
			}
			
			return matchedElement;
		}		
			
		/// <summary>
		/// Finds an element in the schema.
		/// </summary>
		/// <remarks>
		/// Only looks at the elements that are defined in the 
		/// root of the schema so it will not find any elements
		/// that are defined inside any complex types.
		/// </remarks>
		XmlSchemaElement FindElement(XmlQualifiedName name)
		{
			XmlSchemaElement matchedElement = null;
			foreach (XmlSchemaElement element in schema.Elements.Values) {
				if (name.Equals(element.QualifiedName)) {
					matchedElement = element;
					break;
				}
			}
			
			return matchedElement;
		}		
		
		XmlCompletionDataCollection GetChildElementCompletionData(XmlSchemaElement element, string prefix)
		{
			XmlCompletionDataCollection data = new XmlCompletionDataCollection();
			
			XmlSchemaComplexType complexType = GetElementAsComplexType(element);
			
			if (complexType != null) {
				data = GetChildElementCompletionData(complexType, prefix);
			}
				
			return data;
		}
		
		XmlCompletionDataCollection GetChildElementCompletionData(XmlSchemaComplexType complexType, string prefix)
		{
			XmlCompletionDataCollection data = new XmlCompletionDataCollection();
			
			XmlSchemaSequence sequence = complexType.Particle as XmlSchemaSequence;
			XmlSchemaChoice choice = complexType.Particle as XmlSchemaChoice;
			XmlSchemaGroupRef groupRef = complexType.Particle as XmlSchemaGroupRef;
			XmlSchemaComplexContent complexContent = complexType.ContentModel as XmlSchemaComplexContent;
			
			if (sequence != null) {
				data = GetChildElementCompletionData(sequence.Items, prefix);
			} else if (choice != null) {
				data = GetChildElementCompletionData(choice.Items, prefix);				
			} else if (complexContent != null) {
				data = GetChildElementCompletionData(complexContent, prefix);								
			} else if (groupRef != null) {
				data = GetChildElementCompletionData(groupRef, prefix);
			}
				
			return data;
		}
		
		XmlCompletionDataCollection GetChildElementCompletionData(XmlSchemaObjectCollection items, string prefix)
		{
			XmlCompletionDataCollection data = new XmlCompletionDataCollection();
			
			foreach (XmlSchemaObject schemaObject in items) {
				
				XmlSchemaElement childElement = schemaObject as XmlSchemaElement;
				XmlSchemaSequence childSequence = schemaObject as XmlSchemaSequence;
				XmlSchemaChoice childChoice = schemaObject as XmlSchemaChoice;
				XmlSchemaGroupRef groupRef = schemaObject as XmlSchemaGroupRef;
				
				if (childElement != null) {
					string name = childElement.Name;
					if (name == null) {
						name = childElement.RefName.Name;
						XmlSchemaElement element = FindElement(childElement.RefName);
						if (element != null) {
							if (element.IsAbstract) {
								AddSubstitionGroupElements(data, element.QualifiedName, prefix);
							} else {
								AddElement(data, name, prefix, element.Annotation);
							}
						} else {
							AddElement(data, name, prefix, childElement.Annotation);						
						}
					} else {
						AddElement(data, name, prefix, childElement.Annotation);
					}
				} else if (childSequence != null) {
					AddElements(data, GetChildElementCompletionData(childSequence.Items, prefix));
				} else if (childChoice != null) {
					AddElements(data, GetChildElementCompletionData(childChoice.Items, prefix));
				} else if (groupRef != null) {
					AddElements(data, GetChildElementCompletionData(groupRef, prefix));
				}
			}
				
			return data;
		}
		
		XmlCompletionDataCollection GetChildElementCompletionData(XmlSchemaComplexContent complexContent, string prefix)
		{
			XmlCompletionDataCollection data = new XmlCompletionDataCollection();
			
			XmlSchemaComplexContentExtension extension = complexContent.Content as XmlSchemaComplexContentExtension;
			if (extension != null) {
				data = GetChildElementCompletionData(extension, prefix);
			} else {
				XmlSchemaComplexContentRestriction restriction = complexContent.Content as XmlSchemaComplexContentRestriction;
				if (restriction != null) {
					data = GetChildElementCompletionData(restriction, prefix);
				}
			}
			
			return data;
		}
		
		XmlCompletionDataCollection GetChildElementCompletionData(XmlSchemaComplexContentExtension extension, string prefix)
		{
			XmlCompletionDataCollection data = new XmlCompletionDataCollection();
			
			XmlSchemaComplexType complexType = FindNamedType(schema, extension.BaseTypeName);
			if (complexType != null) {
				data = GetChildElementCompletionData(complexType, prefix);
			}
			
			// Add any elements.
			if (extension.Particle != null) {
				XmlSchemaSequence sequence = extension.Particle as XmlSchemaSequence;
				XmlSchemaChoice choice = extension.Particle as XmlSchemaChoice;
				XmlSchemaGroupRef groupRef = extension.Particle as XmlSchemaGroupRef;
				
				if(sequence != null) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -