view Xml/XmlTools.cs @ 116:07660ac09a5f

Merge heads, but keep de0ed24eb961/IBBoard
author IBBoard <dev@ibboard.co.uk>
date Tue, 26 Jun 2012 20:09:01 +0100
parents de0ed24eb961 7ca4acc659bb
children
line source
1 // This file (XmlTools.cs) is a part of the IBBoard library and is copyright 2009 IBBoard
2 //
3 // The file and the library/program it is in are licensed under the GNU LGPL license, either version 3 of the License or (at your option) any later version. Please see COPYING.LGPL for more information and the full license.
4 //
5 using System;
6 using System.Globalization;
7 using System.Text.RegularExpressions;
8 using System.Xml;
9 using System.Xml.Schema;
10 using System.Reflection;
11 using System.IO;
13 namespace IBBoard.Xml
14 {
15 /// <summary>
16 /// Some basic tools for handling XML files and retrieving their values
17 /// </summary>
18 public class XmlTools
19 {
20 private static Regex idRegex;
21 private static Regex multiUnderscoreRegex;
22 private static NumberFormatInfo doubleFormat;
24 /// <summary>
25 /// Gets the value of an attribute of an element as a boolean. Throws a FormatException if the attribute is not a boolean.
26 /// </summary>
27 /// <param name="elem">
28 /// The <see cref="XmlElement"/> to get the attribute value of
29 /// </param>
30 /// <param name="attributeName">
31 /// The name of the attribute to get as a boolean
32 /// </param>
33 /// <returns>
34 /// The value of the attribute as an boolean
35 /// </returns>
36 public static bool GetBoolValueFromAttribute(XmlElement elem, string attributeName)
37 {
38 try
39 {
40 return bool.Parse(elem.GetAttribute(attributeName));
41 }
42 catch (FormatException)
43 {
44 throw new FormatException(String.Format("Attribute '{0}' of {1} with ID {2} was not a valid boolean", attributeName, elem.Name, elem.GetAttribute("id")));
45 }
46 }
48 /// <summary>
49 /// Gets the value of an attribute of an element as an integer. Throws a FormatException if the attribute is not an integer.
50 /// </summary>
51 /// <param name="elem">
52 /// The <see cref="XmlElement"/> to get the attribute value of
53 /// </param>
54 /// <param name="attributeName">
55 /// The name of the attribute to get as an integer
56 /// </param>
57 /// <returns>
58 /// The value of the attribute as an integer
59 /// </returns>
60 public static int GetIntValueFromAttribute(XmlElement elem, string attributeName)
61 {
62 try
63 {
64 return int.Parse(elem.GetAttribute(attributeName));
65 }
66 catch (FormatException)
67 {
68 throw new FormatException(String.Format("Attribute '{0}' of {1} with ID {2} was not a valid number", attributeName, elem.Name, elem.GetAttribute("id")));
69 }
70 }
72 /// <summary>
73 /// Gets the value of an attribute of an element as a double. Throws a FormatException if the attribute is not a double.
74 /// </summary>
75 /// <param name="elem">
76 /// The <see cref="XmlElement"/> to get the attribute value of
77 /// </param>
78 /// <param name="attributeName">
79 /// The name of the attribute to get as a double
80 /// </param>
81 /// <returns>
82 /// The value of the attribute as an double
83 /// </returns>
84 public static double GetDoubleValueFromAttribute(XmlElement elem, string attributeName)
85 {
86 double doubleVal = double.NaN;
87 string attribValue = elem.GetAttribute(attributeName);
89 if (attribValue == "INF")
90 {
91 doubleVal = double.PositiveInfinity;
92 }
93 else
94 {
95 try
96 {
97 return double.Parse(attribValue, GetNumberFormatInfo());
98 }
99 catch (FormatException)
100 {
101 throw new FormatException(String.Format("Attribute '{0}' of {1} with ID {2} was not a valid number", attributeName, elem.Name, elem.GetAttribute("id")));
102 }
103 }
105 return doubleVal;
106 }
108 public static T GetEnumValueFromAttribute<T>(XmlElement elem, string attributeName)
109 {
110 return GetEnumValueFromAttribute<T>(elem, attributeName, true);
111 }
113 public static T GetEnumValueFromAttribute<T>(XmlElement elem, string attributeName, bool ignoreCase)
114 {
115 string attribValue = elem.GetAttribute(attributeName);
117 try
118 {
119 return EnumTools.ParseEnum<T>(attribValue, ignoreCase);
120 }
121 catch (ArgumentException)
122 {
123 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));
124 }
125 }
127 private static NumberFormatInfo GetNumberFormatInfo()
128 {
129 if (doubleFormat == null)
130 {
131 doubleFormat = NumberFormatInfo.InvariantInfo;
132 }
134 return doubleFormat;
135 }
137 private static Regex GetIdRegex()
138 {
139 if (idRegex == null)
140 {
141 idRegex = new Regex("[^a-zA-Z0-9:\\._-]+");
142 }
144 return idRegex;
145 }
147 private static Regex GetMultiUnderscoreRegex()
148 {
149 if (multiUnderscoreRegex == null)
150 {
151 multiUnderscoreRegex = new Regex("_{2,}");
152 }
154 return multiUnderscoreRegex;
155 }
157 /// <summary>
158 /// Gets a valid XML ID for a given string that does not contain accented and non-ASCII characters. Matches the allowed characters
159 /// in the XML spec (http://www.w3.org/TR/xml/#NT-NameStartChar) where the characters do not use Unicode character codes. If the ID
160 /// starts with an invalid character then it will be prepended with an underscore.
161 /// </summary>
162 /// <param name="str">
163 /// The <see cref="System.String"/> to turn in to a valid ID
164 /// </param>
165 /// <returns>
166 /// The valid XML ID with all series of invalid characters replaced with an underscore
167 /// </returns>
168 public static string GetAsciiXmlIdForString(string str)
169 {
170 string id = GetIdRegex().Replace(str, "_");
171 id = GetMultiUnderscoreRegex().Replace(id, "_");
173 if (!IdStartsWithValidCharacter(id))
174 {
175 id = "_" + id;
176 }
178 return id;
179 }
181 private static bool IdStartsWithValidCharacter(string id)
182 {
183 bool valid = false;
185 if (id.Length > 0)
186 {
187 char firstChar = id[0];
188 valid = ('A' <= firstChar && firstChar <= 'Z') || ('a' <= firstChar && firstChar <= 'z') || firstChar == '_' || firstChar == ':';
189 }
191 return valid;
192 }
194 public static void AddSchemaToSetFromResource(XmlSchemaSet schemaSet, string targetNamespace, Assembly assm, string id)
195 {
196 Stream resStream = assm.GetManifestResourceStream(id);
197 schemaSet.Add(targetNamespace, new XmlTextReader(resStream));
198 }
199 }
200 }