Экранирование ТОЛЬКО содержимого узла в XML

#c# #.net #xml #.net-2.0 #c#-2.0

#c# #.net #xml #.net-2.0 #c #-2.0

Вопрос:

У меня есть часть кода, упомянутая ниже.

     //Reading from a file and assign to the variable named "s"
    string s = "<item><name> Foo </name></item>";
    XmlDocument doc = new XmlDocument();
    doc.LoadXml(s);
  

Но он перестает работать, если содержимое содержит символы, похожие на «<«, «>» .. и т.д.

 string s = "<item><name> Foo > Bar </name></item>";
  

Я знаю, мне нужно экранировать эти символы перед загрузкой, но, если мне нравится

  doc.LoadXml(System.Security.SecurityElement.Escape(s));
  

теги (< , > ) также экранируются, и в результате возникает ошибка.

Как я могу решить эту проблему?

Комментарии:

1. Очень сложно рассуждать о недопустимом XML (по сути, это текст с инструкциями). Пожалуйста, подумайте, что вы на самом деле хотите, чтобы программа выполняла в следующем случае <элемент><имя></item>, прежде чем продолжить этот маршрут…

2. @AlexeiLevenkov согласен с Алексеем, но другой способ думать об этом заключается в том, что вы должны попытаться помешать «Foo> Bar» когда-либо стать частью XML. В момент его добавления вы можете просто экранировать его. После того, как XML недействителен, это становится другой историей.

Ответ №1:

сложное решение:

     string s = "<item><name> Foo > Bar </name></item>";
    s = Regex.Replace(s, @"<[^>] ?>", m => HttpUtility.HtmlEncode(m.Value)).Replace("<","ojlovecd").Replace(">","cdloveoj");
    s = HttpUtility.HtmlDecode(s).Replace("ojlovecd", "amp;>").Replace("cdloveoj", "amp;<");
    XmlDocument doc = new XmlDocument();
    doc.LoadXml(s);
  

Ответ №2:

Предполагая, что ваш контент никогда не будет содержать символы «]]>», вы можете использовать CDATA.

 string s = "<item><name><![CDATA[ Foo > Bar ]]></name></item>";
  

В противном случае вам нужно будет кодировать ваши специальные символы в html и декодировать их перед их использованием / отображением (если только это не в браузере).

 string s = "<item><name> Foo amp;> Bar </name></item>";
  

Комментарии:

1. Как говорится в моих комментариях, эти строки считываются из файлов. Они НЕ назначены в моих кодах. Я знаю, что содержимое должно быть закодировано, но в файле много содержимого, и мне может понадобиться много регулярных выражений, чтобы заменить все это в моих строках, я думаю. Я не хочу этих утомительных проверок regx. Итак, мой вопрос в том, как я могу решить эту проблему?

Ответ №3:

Присвойте содержимое строки InnerXml свойству узла.

  var node = doc.CreateElement("root");
 node.InnerXml = s;
  

Взгляните на — Различные способы экранирования XML-строки в C #

Комментарии:

1. Извините. В чем разница? Это то же самое, кроме наличия дополнительного корневого узла. В любом случае, ошибка будет возникать при назначении узлу. Innerxml ? Не будет?

2. @Kai Нет необходимости, если у вас уже есть documentElement (корневой узел).

Ответ №4:

Похоже, что сгенерированные вами строки являются строками, а не допустимым XML. Вы можете либо получить строки, сгенерированные как допустимый XML, ЛИБО, если вы знаете, что строки всегда будут именем, тогда не включайте XML <item> и <name> теги в данные.

Затем, когда вы создаете XMLDocument . выполните a CreateElement и назначьте свою строку перед повторным сохранением результатов.

 XmlDocument doc = new XmlDocument(); 
XmlElement root = doc.CreateElement("item");
doc.AppendChild(root);
XmlElement name = doc.CreateElement("name");
name.InnerText = "the contents from your file";
root.AppendChild(name);