简体   繁体   中英

Set XML as value of an XML node attribute

I'm trying to create an XML document in C# , which in one of attribute will get another XML as value:

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

MyXMLToInsert would be somthing like this:

<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">
.
.

How can I prevent the second XML's special characters not to conflict with the main ones? Thanks.

Different ways how to escape an XML string in C#

XML encoding is necessary if you have to save XML text in an XML document. If you don't escape special chars the XML to insert will become a part of the original XML DOM and not a value of a node.

Escaping the XML means basically replacing 5 chars with new values.

These replacements are:

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

Here are 4 ways you can encode XML in C#:

  1. string.Replace() 5 times

This is ugly but it works. Note that Replace("&", "&") has to be the first replace so we don't replace other already escaped &.

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()

Used for encoding HTML, but HTML is a form of XML so we can use that too. Mostly used in ASP.NET apps. Note that HtmlEncode does NOT encode apostrophes ( ' ).

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()

In Windows Forms or Console apps I use this method. If nothing else it saves me including the System.Web reference in my projects and it encodes all 5 chars.

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

Using XmlTextWriter you don't have to worry about escaping anything since it escapes the chars where needed. For example in the attributes it doesn't escape apostrophes, while in node values it doesn't escape apostrophes and qoutes.

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>
*/

Calling the SetAttribute method will take care of escaping the data.

Say you read the content of MyXMLToInsert from a file "Text.txt" located in the root directory of your application.

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

The value of the attribute would automatically be escaped (using XML escape codes) to...

<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;" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM