Строку в XML
есть ли функция C#, которая может использоваться для экранирования и удаления строки, которая может использоваться для заполнения содержимого элемента XML?
Я использую VSTS 2008 + C# + .Net 3.0.
EDIT 1: я объединяю простой и короткий XML-файл, и я не использую сериализацию, поэтому мне нужно явно экранировать XML-символ вручную, например, мне нужно поставить a<b
на <foo></foo>
, поэтому мне нужна escape-строка a<b
и положить его в элемент foo.
9 ответов:
public static string XmlEscape(string unescaped) { XmlDocument doc = new XmlDocument(); XmlNode node = doc.CreateElement("root"); node.InnerText = unescaped; return node.InnerXml; } public static string XmlUnescape(string escaped) { XmlDocument doc = new XmlDocument(); XmlNode node = doc.CreateElement("root"); node.InnerXml = escaped; return node.InnerText; }
EDIT: вы говорите:"я объединяю простой и короткий XML-файл, и я не использую сериализацию, поэтому мне нужно явно экранировать XML-символ вручную".
Я сильно советую не делать это вручную. Используйте XML API, чтобы сделать все это для вас - прочитайте в исходных файлах, объедините их в один документ, однако вам нужно (вы, вероятно, хотите использовать
XmlDocument.ImportNode
), а затем записать его снова. Вы не хотите писать свои собственные XML-Парсеры/форматтеры. Сериализация здесь несколько неуместна.если вы можете дать нам короткий, но полный пример того, что именно вы пытаетесь сделать, мы можем помочь вам, чтобы избежать беспокоясь о побеге в первую очередь.
оригинальный ответ
не совсем понятно, что вы имеете в виду, но обычно XML-API делают это за вас. Вы устанавливаете текст в узле, и он автоматически экранирует все, что ему нужно. Для пример:
пример LINQ to XML:
using System; using System.Xml.Linq; class Test { static void Main() { XElement element = new XElement("tag", "Brackets & stuff <>"); Console.WriteLine(element); } }
DOM пример:
using System; using System.Xml; class Test { static void Main() { XmlDocument doc = new XmlDocument(); XmlElement element = doc.CreateElement("tag"); element.InnerText = "Brackets & stuff <>"; Console.WriteLine(element.OuterXml); } }
вывод из обоих примеров:
<tag>Brackets & stuff <></tag>
это предполагает, что вы хотите XML экранирования, конечно. Если это не так, пожалуйста, опубликуйте более подробную информацию.
спасибо @sehe за однострочный побег:
var escaped = new System.Xml.Linq.XText(unescaped).ToString();
Я добавляю к нему однострочный un-escape:
var unescapedAgain = System.Xml.XmlReader.Create(new StringReader("<r>" + escaped + "</r>")).ReadElementString();
Джордж, все просто. Всегда используйте API XML для обработки XML. Они делают все выход и невыход для вас.
никогда не создавайте XML путем добавления строк.
и если вы хотите, как я, когда я нашел этот вопрос, чтобы избежать имен узлов XML, например, при чтении из сериализации XML, используйте самый простой способ:
XmlConvert.EncodeName(string nameToEscape)
Он также будет экранировать пробелы и любые недопустимые символы для XML-элементов.
http://msdn.microsoft.com/en-us/library/system.security.securityelement.escape%28VS.80%29.aspx
внимание: Некромантия
еще ответ Дарина Димитрова + система.Безопасность.SecurityElement.Escape (строка s) не завершена.
в XML 1.1 самый простой и безопасный способ-просто кодировать все.
Как	
for \t.
Он вообще не поддерживается в XML 1.0.
Для XML 1.0 одним из возможных обходных путей является кодирование base-64 текста, содержащего символы.//string EncodedXml = SpecialXmlEscape("привет мир"); //Console.WriteLine(EncodedXml); //string DecodedXml = XmlUnescape(EncodedXml); //Console.WriteLine(DecodedXml); public static string SpecialXmlEscape(string input) { //string content = System.Xml.XmlConvert.EncodeName("\t"); //string content = System.Security.SecurityElement.Escape("\t"); //string strDelimiter = System.Web.HttpUtility.HtmlEncode("\t"); // XmlEscape("\t"); //XmlDecode("	"); //strDelimiter = XmlUnescape(";"); //Console.WriteLine(strDelimiter); //Console.WriteLine(string.Format("&#{0};", (int)';')); //Console.WriteLine(System.Text.Encoding.ASCII.HeaderName); //Console.WriteLine(System.Text.Encoding.UTF8.HeaderName); string strXmlText = ""; if (string.IsNullOrEmpty(input)) return input; System.Text.StringBuilder sb = new StringBuilder(); for (int i = 0; i < input.Length; ++i) { sb.AppendFormat("&#{0};", (int)input[i]); } strXmlText = sb.ToString(); sb.Clear(); sb = null; return strXmlText; } // End Function SpecialXmlEscape
XML 1.0:
public static string Base64Encode(string plainText) { var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText); return System.Convert.ToBase64String(plainTextBytes); } public static string Base64Decode(string base64EncodedData) { var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData); return System.Text.Encoding.UTF8.GetString(base64EncodedBytes); }
следующие функции будут выполнять работу. Не тестировал против XmlDocument, но я думаю, что это намного быстрее.
public static string XmlEncode(string value) { System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings { ConformanceLevel = System.Xml.ConformanceLevel.Fragment }; StringBuilder builder = new StringBuilder(); using (var writer = System.Xml.XmlWriter.Create(builder, settings)) { writer.WriteString(value); } return builder.ToString(); } public static string XmlDecode(string xmlEncodedValue) { System.Xml.XmlReaderSettings settings = new System.Xml.XmlReaderSettings { ConformanceLevel = System.Xml.ConformanceLevel.Fragment }; using (var stringReader = new System.IO.StringReader(xmlEncodedValue)) { using (var xmlReader = System.Xml.XmlReader.Create(stringReader, settings)) { xmlReader.Read(); return xmlReader.Value; } } }
использование сторонней библиотеки (Newtonsoft.Json) как вариант:
public static string XmlEncode(string unescaped) { if (unescaped == null) return null; return JsonConvert.SerializeObject(unescaped); ; } public static string XmlDecode(string escaped) { if (escaped == null) return null; return JsonConvert.DeserializeObject(escaped, typeof(string)).ToString(); }
пример:
a<b
"a<b"
<foo></foo>
"foo></foo>"