Mercurial > repos > IBBoard
changeset 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 | e32b5ccda410 |
children | 07660ac09a5f |
files | IBBoard.csproj Xml/XmlResourceResolver.cs Xml/XmlTools.cs |
diffstat | 3 files changed, 222 insertions(+), 177 deletions(-) [+] |
line diff
1.1 --- a/IBBoard.csproj Sun Jun 24 15:48:25 2012 +0100 1.2 +++ b/IBBoard.csproj Mon Jun 25 21:06:25 2012 +0100 1.3 @@ -157,6 +157,7 @@ 1.4 <Compile Include="EqualityChecker.cs" /> 1.5 <Compile Include="IO\StreamUtil.cs" /> 1.6 <Compile Include="Collections\Collections.cs" /> 1.7 + <Compile Include="Xml\XmlResourceResolver.cs" /> 1.8 </ItemGroup> 1.9 <ItemGroup> 1.10 <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/Xml/XmlResourceResolver.cs Mon Jun 25 21:06:25 2012 +0100 2.3 @@ -0,0 +1,40 @@ 2.4 +using System; 2.5 +using System.Xml; 2.6 +using System.Reflection; 2.7 +using System.Collections.Generic; 2.8 +using System.IO; 2.9 +using System.Net; 2.10 + 2.11 +namespace IBBoard.Xml 2.12 +{ 2.13 + public class XmlResourceResolver : XmlUrlResolver 2.14 + { 2.15 + private Assembly assm; 2.16 + private Dictionary<string, string> relativeToUriMap = new Dictionary<string, string>(); 2.17 + 2.18 + public XmlResourceResolver(Assembly assembly) 2.19 + { 2.20 + assm = assembly; 2.21 + } 2.22 + 2.23 + public void AddMapping(string relativeURI, string resourceName) 2.24 + { 2.25 + relativeToUriMap[relativeURI] = resourceName; 2.26 + } 2.27 + 2.28 + public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn) 2.29 + { 2.30 + string absoluteUriString = absoluteUri.ToString(); 2.31 + 2.32 + if (relativeToUriMap.ContainsKey(absoluteUriString)) 2.33 + { 2.34 + string file = relativeToUriMap[absoluteUriString]; 2.35 + Stream stream = assm.GetManifestResourceStream(file); 2.36 + return stream; 2.37 + } 2.38 + 2.39 + return base.GetEntity(absoluteUri, role, ofObjectToReturn); 2.40 + } 2.41 + } 2.42 +} 2.43 +
3.1 --- a/Xml/XmlTools.cs Sun Jun 24 15:48:25 2012 +0100 3.2 +++ b/Xml/XmlTools.cs Mon Jun 25 21:06:25 2012 +0100 3.3 @@ -7,186 +7,190 @@ 3.4 using System.Globalization; 3.5 using System.Text.RegularExpressions; 3.6 using System.Xml; 3.7 +using System.Reflection; 3.8 +using System.IO; 3.9 +using System.Xml.Schema; 3.10 3.11 namespace IBBoard.Xml 3.12 { 3.13 - /// <summary> 3.14 - /// Some basic tools for handling XML files and retrieving their values 3.15 - /// </summary> 3.16 - public class XmlTools 3.17 - { 3.18 - private static Regex idRegex; 3.19 - private static Regex multiUnderscoreRegex; 3.20 - private static NumberFormatInfo doubleFormat; 3.21 + /// <summary> 3.22 + /// Some basic tools for handling XML files and retrieving their values 3.23 + /// </summary> 3.24 + public class XmlTools 3.25 + { 3.26 + private static Regex idRegex; 3.27 + private static Regex multiUnderscoreRegex; 3.28 + private static NumberFormatInfo doubleFormat; 3.29 3.30 - /// <summary> 3.31 - /// Gets the value of an attribute of an element as a boolean. Throws a FormatException if the attribute is not a boolean. 3.32 - /// </summary> 3.33 - /// <param name="elem"> 3.34 - /// The <see cref="XmlElement"/> to get the attribute value of 3.35 - /// </param> 3.36 - /// <param name="attributeName"> 3.37 - /// The name of the attribute to get as a boolean 3.38 - /// </param> 3.39 - /// <returns> 3.40 - /// The value of the attribute as an boolean 3.41 - /// </returns> 3.42 - public static bool GetBoolValueFromAttribute(XmlElement elem, string attributeName) 3.43 - { 3.44 - try 3.45 - { 3.46 - return bool.Parse(elem.GetAttribute(attributeName)); 3.47 - } 3.48 - catch(FormatException) 3.49 - { 3.50 - throw new FormatException(String.Format("Attribute '{0}' of {1} with ID {2} was not a valid boolean", attributeName, elem.Name, elem.GetAttribute("id"))); 3.51 - } 3.52 + /// <summary> 3.53 + /// Gets the value of an attribute of an element as a boolean. Throws a FormatException if the attribute is not a boolean. 3.54 + /// </summary> 3.55 + /// <param name="elem"> 3.56 + /// The <see cref="XmlElement"/> to get the attribute value of 3.57 + /// </param> 3.58 + /// <param name="attributeName"> 3.59 + /// The name of the attribute to get as a boolean 3.60 + /// </param> 3.61 + /// <returns> 3.62 + /// The value of the attribute as an boolean 3.63 + /// </returns> 3.64 + public static bool GetBoolValueFromAttribute(XmlElement elem, string attributeName) 3.65 + { 3.66 + try 3.67 + { 3.68 + return bool.Parse(elem.GetAttribute(attributeName)); 3.69 + } catch (FormatException) 3.70 + { 3.71 + throw new FormatException(String.Format("Attribute '{0}' of {1} with ID {2} was not a valid boolean", attributeName, elem.Name, elem.GetAttribute("id"))); 3.72 + } 3.73 + } 3.74 + 3.75 + /// <summary> 3.76 + /// Gets the value of an attribute of an element as an integer. Throws a FormatException if the attribute is not an integer. 3.77 + /// </summary> 3.78 + /// <param name="elem"> 3.79 + /// The <see cref="XmlElement"/> to get the attribute value of 3.80 + /// </param> 3.81 + /// <param name="attributeName"> 3.82 + /// The name of the attribute to get as an integer 3.83 + /// </param> 3.84 + /// <returns> 3.85 + /// The value of the attribute as an integer 3.86 + /// </returns> 3.87 + public static int GetIntValueFromAttribute(XmlElement elem, string attributeName) 3.88 + { 3.89 + try 3.90 + { 3.91 + return int.Parse(elem.GetAttribute(attributeName)); 3.92 + } catch (FormatException) 3.93 + { 3.94 + throw new FormatException(String.Format("Attribute '{0}' of {1} with ID {2} was not a valid number", attributeName, elem.Name, elem.GetAttribute("id"))); 3.95 + } 3.96 + } 3.97 + 3.98 + /// <summary> 3.99 + /// Gets the value of an attribute of an element as a double. Throws a FormatException if the attribute is not a double. 3.100 + /// </summary> 3.101 + /// <param name="elem"> 3.102 + /// The <see cref="XmlElement"/> to get the attribute value of 3.103 + /// </param> 3.104 + /// <param name="attributeName"> 3.105 + /// The name of the attribute to get as a double 3.106 + /// </param> 3.107 + /// <returns> 3.108 + /// The value of the attribute as an double 3.109 + /// </returns> 3.110 + public static double GetDoubleValueFromAttribute(XmlElement elem, string attributeName) 3.111 + { 3.112 + double doubleVal = double.NaN; 3.113 + string attribValue = elem.GetAttribute(attributeName); 3.114 + 3.115 + if (attribValue == "INF") 3.116 + { 3.117 + doubleVal = double.PositiveInfinity; 3.118 + } else 3.119 + { 3.120 + try 3.121 + { 3.122 + return double.Parse(attribValue, GetNumberFormatInfo()); 3.123 + } catch (FormatException) 3.124 + { 3.125 + throw new FormatException(String.Format("Attribute '{0}' of {1} with ID {2} was not a valid number", attributeName, elem.Name, elem.GetAttribute("id"))); 3.126 + } 3.127 + } 3.128 + 3.129 + return doubleVal; 3.130 + } 3.131 + 3.132 + public static T GetEnumValueFromAttribute<T>(XmlElement elem, string attributeName) 3.133 + { 3.134 + return GetEnumValueFromAttribute<T>(elem, attributeName, true); 3.135 + } 3.136 + 3.137 + public static T GetEnumValueFromAttribute<T>(XmlElement elem, string attributeName, bool ignoreCase) 3.138 + { 3.139 + string attribValue = elem.GetAttribute(attributeName); 3.140 + 3.141 + try 3.142 + { 3.143 + return EnumTools.ParseEnum<T>(attribValue, ignoreCase); 3.144 + } catch (ArgumentException) 3.145 + { 3.146 + 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)); 3.147 + } 3.148 + } 3.149 + 3.150 + private static NumberFormatInfo GetNumberFormatInfo() 3.151 + { 3.152 + if (doubleFormat == null) 3.153 + { 3.154 + doubleFormat = NumberFormatInfo.InvariantInfo; 3.155 + } 3.156 + 3.157 + return doubleFormat; 3.158 + } 3.159 + 3.160 + private static Regex GetIdRegex() 3.161 + { 3.162 + if (idRegex == null) 3.163 + { 3.164 + idRegex = new Regex("[^a-zA-Z0-9:\\._-]+"); 3.165 + } 3.166 + 3.167 + return idRegex; 3.168 + } 3.169 + 3.170 + private static Regex GetMultiUnderscoreRegex() 3.171 + { 3.172 + if (multiUnderscoreRegex == null) 3.173 + { 3.174 + multiUnderscoreRegex = new Regex("_{2,}"); 3.175 + } 3.176 + 3.177 + return multiUnderscoreRegex; 3.178 + } 3.179 + 3.180 + /// <summary> 3.181 + /// Gets a valid XML ID for a given string that does not contain accented and non-ASCII characters. Matches the allowed characters 3.182 + /// in the XML spec (http://www.w3.org/TR/xml/#NT-NameStartChar) where the characters do not use Unicode character codes. If the ID 3.183 + /// starts with an invalid character then it will be prepended with an underscore. 3.184 + /// </summary> 3.185 + /// <param name="str"> 3.186 + /// The <see cref="System.String"/> to turn in to a valid ID 3.187 + /// </param> 3.188 + /// <returns> 3.189 + /// The valid XML ID with all series of invalid characters replaced with an underscore 3.190 + /// </returns> 3.191 + public static string GetAsciiXmlIdForString(string str) 3.192 + { 3.193 + string id = GetIdRegex().Replace(str, "_"); 3.194 + id = GetMultiUnderscoreRegex().Replace(id, "_"); 3.195 + 3.196 + if (!IdStartsWithValidCharacter(id)) 3.197 + { 3.198 + id = "_" + id; 3.199 + } 3.200 + 3.201 + return id; 3.202 + } 3.203 + 3.204 + private static bool IdStartsWithValidCharacter(string id) 3.205 + { 3.206 + bool valid = false; 3.207 + 3.208 + if (id.Length > 0) 3.209 + { 3.210 + char firstChar = id[0]; 3.211 + valid = ('A' <= firstChar && firstChar <= 'Z') || ('a' <= firstChar && firstChar <= 'z') || firstChar == '_' || firstChar == ':'; 3.212 + } 3.213 + 3.214 + return valid; 3.215 + } 3.216 + 3.217 + public static void AddSchemaToSetFromResource(XmlSchemaSet schemaSet, string targetNamespace, Assembly assm, string id) 3.218 + { 3.219 + Stream resStream = assm.GetManifestResourceStream(id); 3.220 + schemaSet.Add(targetNamespace, new XmlTextReader(resStream)); 3.221 + } 3.222 } 3.223 - 3.224 - /// <summary> 3.225 - /// Gets the value of an attribute of an element as an integer. Throws a FormatException if the attribute is not an integer. 3.226 - /// </summary> 3.227 - /// <param name="elem"> 3.228 - /// The <see cref="XmlElement"/> to get the attribute value of 3.229 - /// </param> 3.230 - /// <param name="attributeName"> 3.231 - /// The name of the attribute to get as an integer 3.232 - /// </param> 3.233 - /// <returns> 3.234 - /// The value of the attribute as an integer 3.235 - /// </returns> 3.236 - public static int GetIntValueFromAttribute(XmlElement elem, string attributeName) 3.237 - { 3.238 - try 3.239 - { 3.240 - return int.Parse(elem.GetAttribute(attributeName)); 3.241 - } 3.242 - catch(FormatException) 3.243 - { 3.244 - throw new FormatException(String.Format("Attribute '{0}' of {1} with ID {2} was not a valid number", attributeName, elem.Name, elem.GetAttribute("id"))); 3.245 - } 3.246 - } 3.247 - 3.248 - /// <summary> 3.249 - /// Gets the value of an attribute of an element as a double. Throws a FormatException if the attribute is not a double. 3.250 - /// </summary> 3.251 - /// <param name="elem"> 3.252 - /// The <see cref="XmlElement"/> to get the attribute value of 3.253 - /// </param> 3.254 - /// <param name="attributeName"> 3.255 - /// The name of the attribute to get as a double 3.256 - /// </param> 3.257 - /// <returns> 3.258 - /// The value of the attribute as an double 3.259 - /// </returns> 3.260 - public static double GetDoubleValueFromAttribute(XmlElement elem, string attributeName) 3.261 - { 3.262 - double doubleVal = double.NaN; 3.263 - string attribValue = elem.GetAttribute(attributeName); 3.264 - 3.265 - if (attribValue == "INF") 3.266 - { 3.267 - doubleVal = double.PositiveInfinity; 3.268 - } 3.269 - else 3.270 - { 3.271 - try 3.272 - { 3.273 - return double.Parse(attribValue, GetNumberFormatInfo()); 3.274 - } 3.275 - catch(FormatException) 3.276 - { 3.277 - throw new FormatException(String.Format("Attribute '{0}' of {1} with ID {2} was not a valid number", attributeName, elem.Name, elem.GetAttribute("id"))); 3.278 - } 3.279 - } 3.280 - 3.281 - return doubleVal; 3.282 - } 3.283 - 3.284 - public static T GetEnumValueFromAttribute<T>(XmlElement elem, string attributeName) 3.285 - { 3.286 - return GetEnumValueFromAttribute<T>(elem, attributeName, true); 3.287 - } 3.288 - 3.289 - public static T GetEnumValueFromAttribute<T>(XmlElement elem, string attributeName, bool ignoreCase) 3.290 - { 3.291 - string attribValue = elem.GetAttribute (attributeName); 3.292 - 3.293 - try 3.294 - { 3.295 - return EnumTools.ParseEnum<T>(attribValue, ignoreCase); 3.296 - } 3.297 - catch(ArgumentException) 3.298 - { 3.299 - 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)); 3.300 - } 3.301 - } 3.302 - 3.303 - private static NumberFormatInfo GetNumberFormatInfo() 3.304 - { 3.305 - if (doubleFormat == null) 3.306 - { 3.307 - doubleFormat = NumberFormatInfo.InvariantInfo; 3.308 - } 3.309 - 3.310 - return doubleFormat; 3.311 - } 3.312 - 3.313 - private static Regex GetIdRegex() 3.314 - { 3.315 - if (idRegex == null) 3.316 - { 3.317 - idRegex = new Regex("[^a-zA-Z0-9:\\._-]+"); 3.318 - } 3.319 - 3.320 - return idRegex; 3.321 - } 3.322 - 3.323 - private static Regex GetMultiUnderscoreRegex() 3.324 - { 3.325 - if (multiUnderscoreRegex == null) 3.326 - { 3.327 - multiUnderscoreRegex = new Regex("_{2,}"); 3.328 - } 3.329 - 3.330 - return multiUnderscoreRegex; 3.331 - } 3.332 - 3.333 - /// <summary> 3.334 - /// Gets a valid XML ID for a given string that does not contain accented and non-ASCII characters. Matches the allowed characters 3.335 - /// in the XML spec (http://www.w3.org/TR/xml/#NT-NameStartChar) where the characters do not use Unicode character codes. If the ID 3.336 - /// starts with an invalid character then it will be prepended with an underscore. 3.337 - /// </summary> 3.338 - /// <param name="str"> 3.339 - /// The <see cref="System.String"/> to turn in to a valid ID 3.340 - /// </param> 3.341 - /// <returns> 3.342 - /// The valid XML ID with all series of invalid characters replaced with an underscore 3.343 - /// </returns> 3.344 - public static string GetAsciiXmlIdForString(string str) 3.345 - { 3.346 - string id = GetIdRegex().Replace(str, "_"); 3.347 - id = GetMultiUnderscoreRegex().Replace(id, "_"); 3.348 - 3.349 - if (!IdStartsWithValidCharacter(id)) 3.350 - { 3.351 - id = "_" + id; 3.352 - } 3.353 - 3.354 - return id; 3.355 - } 3.356 - 3.357 - private static bool IdStartsWithValidCharacter(string id) 3.358 - { 3.359 - bool valid = false; 3.360 - 3.361 - if (id.Length > 0) 3.362 - { 3.363 - char firstChar = id[0]; 3.364 - valid = ('A' <= firstChar && firstChar <= 'Z') || ('a' <= firstChar && firstChar <= 'z') || firstChar == '_' || firstChar == ':'; 3.365 - } 3.366 - 3.367 - return valid; 3.368 - } 3.369 - } 3.370 }