wasSharp – Rev 59
?pathlinks?
///////////////////////////////////////////////////////////////////////////
// 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<string, bool> DirectIsSafeXML =
((Expression<Func<string, bool>>)
(data =>
Regex.Replace(data,
@"(" + string.Join(@"|", @"&", @"<", @">", @""", @"'") + @")",
@"", RegexOptions.IgnoreCase | RegexOptions.Multiline)
.IndexOfAny(new[] { '&', '<', '>', '"', '\'' })
.Equals(-1))).Compile();
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Unescapes a string used in XML.
/// </summary>
/// <param name="s">the string to unescape</param>
/// <returns>an XML unescaped string</returns>
public static string UnescapeXML(string s)
{
var t = new Queue<char>();
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 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Escapes a string to be used in XML.
/// </summary>
/// <param name="s">the string to escape</param>
/// <returns>an XML escaped string</returns>
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 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Determines whether a string is safe to use in XML
/// </summary>
/// <param name="data">the string to check</param>
/// <returns>true in case the string is safe</returns>
public static bool IsSafeXML(string data)
{
return DirectIsSafeXML(data);
}
///////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
///////////////////////////////////////////////////////////////////////////
/// <summary>
/// Recursively rename a node by name.
/// </summary>
/// <param name="root">the root from where to start</param>
/// <param name="name">the name to replace</param>
/// <param name="rename">the name to replace with</param>
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);
}
}
}
}