Экранирование символов новой строки с помощью XmlDocument - PullRequest
4 голосов
/ 02 марта 2011

Мое приложение генерирует XML с использованием XmlDocument. Некоторые данные содержат символы новой строки и возврата каретки.

Когда текст назначается элементу Xml следующим образом:

   e.InnerText = "Hello\nThere";

Полученный XML выглядит так:

<e>Hello
There</e>

Получатель XML (который я не могу контролировать) обрабатывает новую строку как пробел и видит приведенный выше текст как:

 "Hello There"

Чтобы получатель сохранил новую строку, он должен иметь следующую кодировку:

<e>Hello&#xA;There</e>

Если данные применяются к XmlAttribute, новая строка правильно кодируется.

Я пытался применить текст к XmlElement, используя InnerText и InnerXml, но вывод одинаков для обоих.

Есть ли способ получить текстовые узлы XmlElement для вывода новых строк и возврата каретки в их закодированных формах?

Вот пример кода для демонстрации проблемы:

string s = "return[\r] newline[\n] special[&<>\"']";
XmlDocument d = new XmlDocument();
d.AppendChild( d.CreateXmlDeclaration( "1.0", null, null ) );
XmlElement  r = d.CreateElement( "root" );
d.AppendChild( r );
XmlElement  e = d.CreateElement( "normal" );
r.AppendChild( e );
XmlAttribute a = d.CreateAttribute( "attribute" );
e.Attributes.Append( a );
a.Value = s;
e.InnerText = s;
s = s
    .Replace( "&" , "&amp;"  )
    .Replace( "<" , "&lt;"   )
    .Replace( ">" , "&gt;"   )
    .Replace( "\"", "&quot;" )
    .Replace( "'" , "&apos;" )
    .Replace( "\r", "&#xD;"  )
    .Replace( "\n", "&#xA;"  )
;
e = d.CreateElement( "encoded" );
r.AppendChild( e );
a = d.CreateAttribute( "attribute" );
e.Attributes.Append( a );
a.InnerXml = s;
e.InnerXml = s;
d.Save( @"C:\Temp\XmlNewLineHandling.xml" );

Вывод этой программы:

<?xml version="1.0"?>
<root>
  <normal attribute="return[&#xD;] newline[&#xA;] special[&amp;&lt;&gt;&quot;']">return[
] newline[
] special[&amp;&lt;&gt;"']</normal>
  <encoded attribute="return[&#xD;] newline[&#xA;] special[&amp;&lt;&gt;&quot;']">return[
] newline[
] special[&amp;&lt;&gt;"']</encoded>
</root>

Заранее спасибо. Крис.

Ответы [ 4 ]

1 голос
/ 02 марта 2011

Как насчет использования HttpUtility.HtmlEncode()?
http://msdn.microsoft.com/en-us/library/73z22y6h.aspx

ОК, извините за неправильный вывод. HttpUtility.HtmlEncode() будет не решать проблему новой строки, с которой вы столкнулись.

Эта ссылка на блог поможет вам, хотя
http://weblogs.asp.net/mschwarz/archive/2004/02/16/73675.aspx

По сути, обработка новой строки контролируется атрибутом xml:space="preserve".

Пример рабочего кода:

XmlDocument doc = new XmlDocument();
doc.LoadXml("<ROOT/>");
doc.DocumentElement.InnerText = "1234\r\n5678";

XmlAttribute e = doc.CreateAttribute(
    "xml", 
    "space", 
    "http://www.w3.org/XML/1998/namespace");
e.Value = "preserve";
doc.DocumentElement.Attributes.Append(e);

var child = doc.CreateElement("CHILD");
child.InnerText = "1234\r\n5678";
doc.DocumentElement.AppendChild(child);

Console.WriteLine(doc.InnerXml);
Console.ReadLine();

Вывод будет читать:

<ROOT xml:space="preserve">1234
5678<CHILD>1234
5678</CHILD></ROOT>
0 голосов
/ 03 сентября 2011

У меня была такая же проблема Сохранение возвратов каретки при записи / чтении из XML-файла с использованием asp.net

решение состоит в том, чтобы заменить пространство XML на пространство HTML после создания HTML, я добавляюэто

        strHtml = strHtml.Replace("&lt;br/&gt;", "<br/>");

в конце метода перед закрытием потокового считывателя

0 голосов
/ 02 марта 2011

В .net 2.0 используйте XmlDocument PreserveWhitespace switch

XmlDocument d = new XmlDocument();
d.PreserveWhitespace = true;
0 голосов
/ 02 марта 2011

Кодирование - это, вероятно, ваша лучшая ставка с использованием методов , описанных здесь . Или, возможно, вы могли бы вместо этого использовать раздел CData для своего контента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...