Установить XML как значение атрибута узла XML

Я пытаюсь создать XML документ в C#, который в одном из атрибутов получит другой XML в качестве значения:

XmlDocument doc = new XmlDocument();
XmlElement nodElement = doc.CreateElement(string.Empty, "node", string.Empty);
                nodElement.SetAttribute("text", MyXMLToInsert);
doc.AppendChild(nodElement);

MyXMLToInsert было бы что-то вроде этого:

<xml xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns:m="http://schemas.microsoft.com/office/2004/12/omml"
xmlns="http://www.w3.org/TR/REC-html40">

<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
.
.

Как я могу предотвратить вторые специальные символы XML, чтобы они не конфликтовали с основными? Благодарю.

2 ответа

Решение

Вызов метода SetAttribute позаботится о экранировании данных.

Скажем, вы читаете содержимое MyXMLToInsert из файла "Text.txt", расположенного в корневом каталоге вашего приложения.

var doc = new XmlDocument();
        var nodElement = doc.CreateElement(string.Empty, "node", string.Empty);
        nodElement.SetAttribute("text", File.ReadAllText("text.txt"));
        doc.AppendChild(nodElement);

Значение атрибута будет автоматически экранировано (используя escape-коды XML) в...

<node text="&lt;xml xmlns:o=&quot;urn:schemas-microsoft-com:office:office&quot;&#xD;&#xA;xmlns:w=&quot;urn:schemas-microsoft-com:office:word&quot;&#xD;&#xA;xmlns:m=&quot;http://schemas.microsoft.com/office/2004/12/omml&quot;&#xD;&#xA;xmlns=&quot;http://www.w3.org/TR/REC-html40&quot;&gt;&#xD;&#xA;&#xD;&#xA;&lt;head&gt;&#xD;&#xA;&lt;meta http-equiv=Content-Type content=&quot;text/html; charset=utf-8&quot;&gt;" />

Различные способы, как экранировать строку XML в C#

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

Выход из XML означает в основном замену 5 символов новыми значениями.

Эти замены:

<   ->  &lt;
>   ->  &gt;
"   ->  &quot;
'   ->  &apos;
&   ->  &amp;

Вот 4 способа кодирования XML в C#:

  1. string.Replace() 5 times

Это некрасиво, но это работает. Обратите внимание, что замена ("&", "&") должна быть первой заменой, чтобы мы не заменяли другие, уже сбежавшие &.

string xml = "<node>it's my \"node\" & i like it<node>";
encodedXml = xml.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;").Replace("\"", "&quot;").Replace("'", "&apos;");

// RESULT: &lt;node&gt;it&apos;s my &quot;node&quot; &amp; i like it&lt;node&gt;
  1. System.Web.HttpUtility.HtmlEncode()

Используется для кодирования HTML, но HTML является формой XML, поэтому мы тоже можем это использовать. В основном используется в приложениях ASP.NET. Обратите внимание, что HtmlEncode НЕ кодирует апострофы ( ').

string xml = "<node>it's my \"node\" & i like it<node>";
string encodedXml = HttpUtility.HtmlEncode(xml);

// RESULT: &lt;node&gt;it's my &quot;node&quot; &amp; i like it&lt;node&gt;
  1. System.Security.SecurityElement.Escape()

В Windows Forms или Консольных приложениях я использую этот метод. Если ничего другого, это спасает меня, включая ссылку System.Web в моих проектах, и он кодирует все 5 символов.

string xml = "<node>it's my \"node\" & i like it<node>";
string encodedXml = System.Security.SecurityElement.Escape(xml);

// RESULT: &lt;node&gt;it&apos;s my &quot;node&quot; &amp; i like it&lt;node&gt;
  1. System.Xml.XmlTextWriter

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

string xml = "<node>it's my \"node\" & i like it<node>";
using (XmlTextWriter xtw = new XmlTextWriter(@"c:\xmlTest.xml", Encoding.Unicode))
{
    xtw.WriteStartElement("xmlEncodeTest");
    xtw.WriteAttributeString("testAttribute", xml);
    xtw.WriteString(xml);
    xtw.WriteEndElement();
}

// RESULT:
/*
<xmlEncodeTest testAttribute="&lt;node&gt;it's my &quot;node&quot; &amp; i like it&lt;node&gt;">
    &lt;node&gt;it's my "node" &amp; i like it&lt;node&gt;
</xmlEncodeTest>
*/
Другие вопросы по тегам