diff Xml/XmlTools.cs @ 114:7ca4acc659bb

* Add resource resolver for use with DTDs as resources * Add helper method for loading schemas into a set from resources
author IBBoard <dev@ibboard.co.uk>
date Mon, 25 Jun 2012 21:06:25 +0100
parents 8fe11cd7d3bf
children 07660ac09a5f
line wrap: on
line diff
--- a/Xml/XmlTools.cs	Sun Jun 24 15:48:25 2012 +0100
+++ b/Xml/XmlTools.cs	Mon Jun 25 21:06:25 2012 +0100
@@ -7,186 +7,190 @@
 using System.Globalization;
 using System.Text.RegularExpressions;
 using System.Xml;
+using System.Reflection;
+using System.IO;
+using System.Xml.Schema;
 
 namespace IBBoard.Xml
 {
-	/// <summary>
-	/// Some basic tools for handling XML files and retrieving their values
-	/// </summary>
-	public class XmlTools
-	{
-		private static Regex idRegex;
-		private static Regex multiUnderscoreRegex;
-		private static NumberFormatInfo doubleFormat;
-
 		/// <summary>
-		/// Gets the value of an attribute of an element as a boolean. Throws a FormatException if the attribute is not a boolean.
-		/// </summary>
-		/// <param name="elem">
-		/// The <see cref="XmlElement"/> to get the attribute value of
-		/// </param>
-		/// <param name="attributeName">
-		/// The name of the attribute to get as a boolean
-		/// </param>
-		/// <returns>
-		/// The value of the attribute as an boolean
-		/// </returns>
-		public static bool GetBoolValueFromAttribute(XmlElement elem, string attributeName)
-		{
-			try
-			{
-				return bool.Parse(elem.GetAttribute(attributeName));
-			}
-			catch(FormatException)
-			{
-				throw new FormatException(String.Format("Attribute '{0}' of {1} with ID {2} was not a valid boolean", attributeName, elem.Name, elem.GetAttribute("id")));
-			}
-		}
-		
-		/// <summary>
-		/// Gets the value of an attribute of an element as an integer. Throws a FormatException if the attribute is not an integer.
+		/// Some basic tools for handling XML files and retrieving their values
 		/// </summary>
-		/// <param name="elem">
-		/// The <see cref="XmlElement"/> to get the attribute value of
-		/// </param>
-		/// <param name="attributeName">
-		/// The name of the attribute to get as an integer
-		/// </param>
-		/// <returns>
-		/// The value of the attribute as an integer
-		/// </returns>
-		public static int GetIntValueFromAttribute(XmlElement elem, string attributeName)
+		public class XmlTools
 		{
-			try
-			{
-				return int.Parse(elem.GetAttribute(attributeName));
-			}
-			catch(FormatException)
-			{
-				throw new FormatException(String.Format("Attribute '{0}' of {1} with ID {2} was not a valid number", attributeName, elem.Name, elem.GetAttribute("id")));
-			}
-		}
+				private static Regex idRegex;
+				private static Regex multiUnderscoreRegex;
+				private static NumberFormatInfo doubleFormat;
+
+				/// <summary>
+				/// Gets the value of an attribute of an element as a boolean. Throws a FormatException if the attribute is not a boolean.
+				/// </summary>
+				/// <param name="elem">
+				/// The <see cref="XmlElement"/> to get the attribute value of
+				/// </param>
+				/// <param name="attributeName">
+				/// The name of the attribute to get as a boolean
+				/// </param>
+				/// <returns>
+				/// The value of the attribute as an boolean
+				/// </returns>
+				public static bool GetBoolValueFromAttribute(XmlElement elem, string attributeName)
+				{
+						try
+						{
+								return bool.Parse(elem.GetAttribute(attributeName));
+						} catch (FormatException)
+						{
+								throw new FormatException(String.Format("Attribute '{0}' of {1} with ID {2} was not a valid boolean", attributeName, elem.Name, elem.GetAttribute("id")));
+						}
+				}
+		
+				/// <summary>
+				/// Gets the value of an attribute of an element as an integer. Throws a FormatException if the attribute is not an integer.
+				/// </summary>
+				/// <param name="elem">
+				/// The <see cref="XmlElement"/> to get the attribute value of
+				/// </param>
+				/// <param name="attributeName">
+				/// The name of the attribute to get as an integer
+				/// </param>
+				/// <returns>
+				/// The value of the attribute as an integer
+				/// </returns>
+				public static int GetIntValueFromAttribute(XmlElement elem, string attributeName)
+				{
+						try
+						{
+								return int.Parse(elem.GetAttribute(attributeName));
+						} catch (FormatException)
+						{
+								throw new FormatException(String.Format("Attribute '{0}' of {1} with ID {2} was not a valid number", attributeName, elem.Name, elem.GetAttribute("id")));
+						}
+				}
 							
-		/// <summary>
-		/// Gets the value of an attribute of an element as a double. Throws a FormatException if the attribute is not a double.
-		/// </summary>
-		/// <param name="elem">
-		/// The <see cref="XmlElement"/> to get the attribute value of
-		/// </param>
-		/// <param name="attributeName">
-		/// The name of the attribute to get as a double
-		/// </param>
-		/// <returns>
-		/// The value of the attribute as an double
-		/// </returns>
-		public static double GetDoubleValueFromAttribute(XmlElement elem, string attributeName)
-		{
-			double doubleVal = double.NaN;
-			string attribValue = elem.GetAttribute(attributeName);
+				/// <summary>
+				/// Gets the value of an attribute of an element as a double. Throws a FormatException if the attribute is not a double.
+				/// </summary>
+				/// <param name="elem">
+				/// The <see cref="XmlElement"/> to get the attribute value of
+				/// </param>
+				/// <param name="attributeName">
+				/// The name of the attribute to get as a double
+				/// </param>
+				/// <returns>
+				/// The value of the attribute as an double
+				/// </returns>
+				public static double GetDoubleValueFromAttribute(XmlElement elem, string attributeName)
+				{
+						double doubleVal = double.NaN;
+						string attribValue = elem.GetAttribute(attributeName);
 			
-			if (attribValue == "INF")
-			{
-				doubleVal = double.PositiveInfinity;
-			}
-			else
-			{
-				try
-				{
-					return double.Parse(attribValue, GetNumberFormatInfo());
-				}
-				catch(FormatException)
-				{
-					throw new FormatException(String.Format("Attribute '{0}' of {1} with ID {2} was not a valid number", attributeName, elem.Name, elem.GetAttribute("id")));
-				}
-			}
+						if (attribValue == "INF")
+						{
+								doubleVal = double.PositiveInfinity;
+						} else
+						{
+								try
+								{
+										return double.Parse(attribValue, GetNumberFormatInfo());
+								} catch (FormatException)
+								{
+										throw new FormatException(String.Format("Attribute '{0}' of {1} with ID {2} was not a valid number", attributeName, elem.Name, elem.GetAttribute("id")));
+								}
+						}
 			
-			return doubleVal;
-		}
+						return doubleVal;
+				}
 		
-		public static T GetEnumValueFromAttribute<T>(XmlElement elem, string attributeName)
-		{
-			return GetEnumValueFromAttribute<T>(elem, attributeName, true);
-		}
+				public static T GetEnumValueFromAttribute<T>(XmlElement elem, string attributeName)
+				{
+						return GetEnumValueFromAttribute<T>(elem, attributeName, true);
+				}
 		
-		public static T GetEnumValueFromAttribute<T>(XmlElement elem, string attributeName, bool ignoreCase)
-		{
-			string attribValue = elem.GetAttribute (attributeName);
+				public static T GetEnumValueFromAttribute<T>(XmlElement elem, string attributeName, bool ignoreCase)
+				{
+						string attribValue = elem.GetAttribute(attributeName);
 			
-			try
-			{
-				return EnumTools.ParseEnum<T>(attribValue, ignoreCase);
-			}
-			catch(ArgumentException)
-			{
-				throw new FormatException(String.Format("Attribute '{0}' with value {1} for {2} with ID '{3}' was not a valid {4} enum", attributeName, attribValue, elem.Name, elem.GetAttribute("id"), typeof(T).Name));
-			}
-		}
+						try
+						{
+								return EnumTools.ParseEnum<T>(attribValue, ignoreCase);
+						} catch (ArgumentException)
+						{
+								throw new FormatException(String.Format("Attribute '{0}' with value {1} for {2} with ID '{3}' was not a valid {4} enum", attributeName, attribValue, elem.Name, elem.GetAttribute("id"), typeof(T).Name));
+						}
+				}
 
-		private static NumberFormatInfo GetNumberFormatInfo()
-		{
-			if (doubleFormat == null)
-			{
-				doubleFormat = NumberFormatInfo.InvariantInfo;
-			}
+				private static NumberFormatInfo GetNumberFormatInfo()
+				{
+						if (doubleFormat == null)
+						{
+								doubleFormat = NumberFormatInfo.InvariantInfo;
+						}
 
-			return doubleFormat;
-		}
+						return doubleFormat;
+				}
 
-		private static Regex GetIdRegex()
-		{
-			if (idRegex == null)
-			{
-				idRegex = new Regex("[^a-zA-Z0-9:\\._-]+");
-			}
+				private static Regex GetIdRegex()
+				{
+						if (idRegex == null)
+						{
+								idRegex = new Regex("[^a-zA-Z0-9:\\._-]+");
+						}
 			
-			return idRegex;
-		}
+						return idRegex;
+				}
 		
-		private static Regex GetMultiUnderscoreRegex()
-		{
-			if (multiUnderscoreRegex == null)
-			{
-				multiUnderscoreRegex = new Regex("_{2,}");
-			}
+				private static Regex GetMultiUnderscoreRegex()
+				{
+						if (multiUnderscoreRegex == null)
+						{
+								multiUnderscoreRegex = new Regex("_{2,}");
+						}
 			
-			return multiUnderscoreRegex;
-		}
+						return multiUnderscoreRegex;
+				}
 		
-		/// <summary>
-		/// Gets a valid XML ID for a given string that does not contain accented and non-ASCII characters. Matches the allowed characters
-		/// in the XML spec (http://www.w3.org/TR/xml/#NT-NameStartChar) where the characters do not use Unicode character codes. If the ID
-		/// starts with an invalid character then it will be prepended with an underscore.
-		/// </summary>
-		/// <param name="str">
-		/// The <see cref="System.String"/> to turn in to a valid ID
-		/// </param>
-		/// <returns>
-		/// The valid XML ID with all series of invalid characters replaced with an underscore
-		/// </returns>
-		public static string GetAsciiXmlIdForString(string str)
-		{
-			string id = GetIdRegex().Replace(str, "_");
-			id = GetMultiUnderscoreRegex().Replace(id, "_");
+				/// <summary>
+				/// Gets a valid XML ID for a given string that does not contain accented and non-ASCII characters. Matches the allowed characters
+				/// in the XML spec (http://www.w3.org/TR/xml/#NT-NameStartChar) where the characters do not use Unicode character codes. If the ID
+				/// starts with an invalid character then it will be prepended with an underscore.
+				/// </summary>
+				/// <param name="str">
+				/// The <see cref="System.String"/> to turn in to a valid ID
+				/// </param>
+				/// <returns>
+				/// The valid XML ID with all series of invalid characters replaced with an underscore
+				/// </returns>
+				public static string GetAsciiXmlIdForString(string str)
+				{
+						string id = GetIdRegex().Replace(str, "_");
+						id = GetMultiUnderscoreRegex().Replace(id, "_");
+			
+						if (!IdStartsWithValidCharacter(id))
+						{
+								id = "_" + id;
+						}
 			
-			if (!IdStartsWithValidCharacter(id))
-			{
-				id = "_" + id;
-			}
-			
-			return id;
-		}
+						return id;
+				}
 		
-		private static bool IdStartsWithValidCharacter(string id)
-		{
-			bool valid = false;
+				private static bool IdStartsWithValidCharacter(string id)
+				{
+						bool valid = false;
+			
+						if (id.Length > 0)
+						{
+								char firstChar = id[0];
+								valid = ('A' <= firstChar && firstChar <= 'Z') || ('a' <= firstChar && firstChar <= 'z') || firstChar == '_' || firstChar == ':';
+						}
 			
-			if (id.Length > 0)
-			{
-				char firstChar = id[0];
-				valid = ('A' <= firstChar && firstChar <= 'Z') || ('a' <= firstChar && firstChar <= 'z') || firstChar == '_' || firstChar == ':';
-			}
-			
-			return valid;
+						return valid;
+				}
+
+				public static void AddSchemaToSetFromResource(XmlSchemaSet schemaSet, string targetNamespace, Assembly assm, string id)
+				{
+						Stream resStream = assm.GetManifestResourceStream(id);
+						schemaSet.Add(targetNamespace, new XmlTextReader(resStream));
+				}
 		}
-	}
 }