2009-07-15 2 views
76

Есть ли какая-либо функция C#, которая может использоваться для удаления и удаления строки, которая может использоваться для заполнения содержимого элемента XML?Устранение строк в XML

Я использую VSTS 2008 + C# + .Net 3.0.

EDIT 1: Я конкатенации простой и короткий файл XML, и я не использую сериализации, так что мне нужно явно избежать XML характер вручную, например, мне нужно поставить a<b в <foo></foo>, так что мне нужно бежать строку a<b и поместите его в элемент foo.

+13

Кратчайший я могу думать: 'новый XText (неэкранированный) .ToString()' – sehe

+2

Для любого другого спотыкаясь на это, я обнаружил, что это будет лучше ответ: http://stackoverflow.com/a/5304827/1224069 –

+0

Не один путь, но вот несколько: [http://weblogs.sqlteam.com/mladenp/archive/2008/10/21/Different- пути, как к побегу-ан-строка-в-C.aspx XML] (http://weblogs.sqlteam.com/mladenp/archive/2008/10/21/Different-ways-how-to-escape -an-XML-string-in-C.aspx) – marcc

ответ

62
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; 
} 
+5

Вам даже не нужно добавлять элемент в документ. Тем не менее, я бы сказал, что лучше не пытаться это делать в первую очередь - похоже, что Джордж делает работу для себя, делая вещи вручную ... –

+0

Полностью согласен с тобой Джон. Я не знал, что нет необходимости добавлять узел, чтобы он работал. Вот почему я люблю StackOverflow - я каждый день изучаю так много вещей. –

+11

Мне очень не нравится этот ответ, потому что он слишком тяжелый. XmlDocument собирается использовать XmlReader/XmlWriter для выполнения реальной работы, поэтому почему бы не перерезать погоню и избежать этого тяжелого DOM? –

32

EDIT: Вы говорите: «Я конкатенирую простой и короткий XML-файл, и я не использую сериализацию, поэтому мне нужно явно избежать символа XML вручную».

Я бы сильно советую вам не делать это вручную. Используйте XML API, чтобы сделать все это для вас - прочитайте в исходных файлах, объедините их в один документ, но вам нужно (вы, вероятно, захотите использовать XmlDocument.ImportNode), а затем запишите его снова. Вы не хотите писать свои собственные синтаксические анализаторы XML/форматировщики. Сериализация здесь несколько неактуальна.

Если вы можете дать нам короткий, но полный пример того, что вы пытаетесь сделать, мы, вероятно, можем помочь вам избежать необходимости беспокоиться о побеге в первую очередь.


Оригинальный ответ

Это не совсем понятно, что вы имеете в виду, но, как правило XML API, сделать это для вас. Вы устанавливаете текст в узле, и он автоматически избегает всего, что ему нужно. Например:

LINQ к 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 &amp; stuff &lt;&gt;</tag> 

Это предполагает, что вы хотите, чтобы XML-экранирование, конечно. Если вы этого не сделаете, напишите более подробную информацию.

+0

Спасибо, Джон, я добавил больше подробностей в свое первоначальное сообщение EDIT 1. Цените, если вы можете дать мне несколько комментариев и советов. :-) – George2

+0

«после выхода XML» - вы имеете в виду? Не могли бы вы рассказать другими словами? Английский не мой родной язык. :-) – George2

+0

Привет, Jon, как уклониться от XML-формата в обычный строковый формат, т. Е. Из ввода «Скобки & < >», мы получаем выход «Скобки и прочее»? – George2

9

George, это просто. Всегда используйте XML API для обработки XML. Они делают все возможное и ускоряя для вас.

Никогда не создавайте XML путем добавления строк.

+0

Слова, на которых можно жить. Существует много вариантов API XML, но единственное, о чем мы все должны договориться, заключается в том, что ручная конкатенация строк неприемлема. –

+0

Хотя я в целом согласен с этим, могут быть некоторые очень редкие случаи, когда может потребоваться ручное экранирование. Например, при создании документации XML с использованием Roslyn. – svick

+0

@svick: почему бы не создать XML, используя LINQ to XML, а затем использовать .ToString()? –

103
+4

Этот ответ избегает цитат, в отличие от выбранного ответа. – Will

+0

Этот ответ, похоже, не работает с недопустимыми символами, такими как – Haacked

+12

И как вам избежать? – Gondy

2

Эти функции будут выполнять работу. Не тестировал 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; 
     } 
    } 
} 
18

Благодаря @sehe для выхода одной строки:

var escaped = new System.Xml.Linq.XText(unescaped).ToString(); 

добавить к нему одну строку ип-побег:

var unescapedAgain = System.Xml.XmlReader.Create(new StringReader("<r>" + escaped + "</r>")).ReadElementString(); 
+2

Это, похоже, не обрабатывает кавычки '' 'правильно –

+0

XText не избегает кавычек. –

2

И если вы хотите, например, когда я нашел этот вопрос, чтобы избежать имен узлов XML, например, при чтении из сериализации XML, используйте самый простой способ:

XmlConvert.EncodeName(string nameToEscape) 

Он также избежит пробелов и любых недействительных символов для элементов XML.

http://msdn.microsoft.com/en-us/library/system.security.securityelement.escape%28VS.80%29.aspx

+0

Я думаю, на основе вопросов, что они просто хотят получить внутренний текст. Ваше решение будет работать, но несколько переборщило, поскольку оно предназначено также обрабатывать такие вещи, как имена элементов и атрибутов. \ –

+0

Ну, я попытался убежать от имен узлов и подумал, что мои результаты могут помочь кому-либо в будущем. Я также не понимаю, что такое «перебор», но все в порядке.;) – CharlieBrown

+0

Oh , это полезная информация. :) Я просто подумал, что я хотел бы указать, что одна из причин, по которой вы, возможно, не поддержали, заключалась в том, что люди могут чувствовать, что вы не отвечаете на этот вопрос. –

3

ВНИМАНИЕ: Necromancing

Еще ответ + System.Security.SecurityElement.Escape (строка s) Дарин Димитрова не является полным.

В XML 1.1 самым простым и безопасным способом является просто кодирование ВСЕ.
для \ 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("&#09;"); 
    //strDelimiter = XmlUnescape("&#59;"); 
    //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); 
} 
+0

Итак, в XML 1.1, как это сделать вы избегаете всего? –

+0

@Philip Pittle: см. SpecialXmlEscape –

Смежные вопросы