/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // // rights of fair usage, the disclaimer and warranty conditions. // /////////////////////////////////////////////////////////////////////////// using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Xml.Linq; namespace wasSharp.Languages { public static class XML { private static readonly Func DirectIsSafeXML = ((Expression>) (data => Regex.Replace(data, @"(" + string.Join(@"|", @"&", @"<", @">", @""", @"'") + @")", @"", RegexOptions.IgnoreCase | RegexOptions.Multiline) .IndexOfAny(new[] { '&', '<', '>', '"', '\'' }) .Equals(-1))).Compile(); /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// /// Unescapes a string used in XML. /// /// the string to unescape /// an XML unescaped string public static string UnescapeXML(string s) { var t = new Queue(); var m = new StringBuilder(); foreach (var c in s) { switch (c) { case '&': if (!t.Count().Equals(0)) { m.Append(string.Join("", t.ToArray())); t.Clear(); } t.Enqueue(c); break; case ';': if (!t.Count().Equals(0)) { t.Enqueue(c); var special = string.Join("", t.ToArray()); switch (special) { case "'": m.Append('\''); break; case """: m.Append('"'); break; case ">": m.Append('>'); break; case "<": m.Append('<'); break; case "&": m.Append('&'); break; default: // Unrecognized escape sequence m.Append(special); break; } t.Clear(); break; } m.Append(c); break; default: if (!t.Count().Equals(0)) { t.Enqueue(c); if (t.Count() >= 6) { m.Append(string.Join("", t.ToArray())); t.Clear(); } break; } m.Append(c); break; } } return m.ToString(); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// /// Escapes a string to be used in XML. /// /// the string to escape /// an XML escaped string public static string EscapeXML(string s) { if (string.IsNullOrEmpty(s)) return s; var result = new string[s.Length]; Parallel.ForEach(Enumerable.Range(0, s.Length), o => { switch (s[o]) { case '&': result[o] = @"&"; break; case '<': result[o] = @"<"; break; case '>': result[o] = @">"; break; case '"': result[o] = @"""; break; case '\'': result[o] = @"'"; break; default: result[o] = s[o].ToString(); break; } }); return string.Join("", result); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// /// Determines whether a string is safe to use in XML /// /// the string to check /// true in case the string is safe public static bool IsSafeXML(string data) { return DirectIsSafeXML(data); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// /// /// Recursively rename a node by name. /// /// the root from where to start /// the name to replace /// the name to replace with public static void RenameNodes(XElement root, string name, string rename) { if (string.Equals(root.Name.LocalName, name, StringComparison.Ordinal)) { root.Name = rename; } foreach (var xElement in root.Elements()) { RenameNodes(xElement, name, rename); } } } }