title: Remove Namespace attribute from Xml Node in Serialized Value
body: <p>I'm having to recreate a vendor's XML file.  I don't have access to their code, schema, or anything, so I'm doing this using the <code>XmlSerializer</code> and attributes.  I'm doing it this way because the system is using a generic <code>XmlWriter</code> I've built to write other system XML files, so I'm killing two birds with one stone.  Everything has been working out great, with exception of one property value.  The vendor XML looks like this:</p>
  
  <pre><code>&lt;TextOutlTxt&gt;
      &lt;p style="text-align:left;margin-top:0pt;margin-bottom:0pt;"&gt;
         &lt;span&gt;SUBSTA SF6 CIRCUIT BKR CONC FDN &amp;#x22;C&amp;#x22;&lt;/span&gt;
      &lt;/p&gt;
  &lt;/TextOutlTxt&gt;
  </code></pre>
  
  <p>Here's my property configuration:</p>
  
  <pre><code>    private string _value;
  
      [XmlElement("TextOutlTxt")]
      public XmlNode Value
      {
          get
          {
              string text = _value;
              text = Regex.Replace(text, @"[\a\b\f\n\r\t\v\\""'&amp;&lt;&gt;]", m =&gt; string.Join(string.Empty, m.Value.Select(c =&gt; string.Format("&amp;#x{0:X};", Convert.ToInt32(c))).ToArray()));
              string value = "\n&lt;p style=\"text-align:left;margin-top:0pt;margin-bottom:0pt;\"&gt;\n&lt;span&gt;ReplaceMe&lt;/span&gt;\n&lt;/p&gt;\n";
  
              XmlDocument document = new XmlDocument();
              document.InnerXml = "&lt;root&gt;" + value + "&lt;/root&gt;";
  
              XmlNode innerNode = document.DocumentElement.FirstChild;
              innerNode.InnerText = text;
  
              return innerNode;
          }
          set
          { }
      }
  </code></pre>
  
  <p>And this gives me:</p>
  
  <pre><code>&lt;TextOutlTxt&gt;
    &lt;p style="text-align:left;margin-top:0pt;margin-bottom:0pt;" xmlns=""&gt;SUBSTA SF6 CIRCUIT BKR CONC FDN &amp;amp;#x22;C&amp;amp;#x22;&lt;/p&gt;
  &lt;/TextOutlTxt&gt;
  </code></pre>
  
  <p>So I'm close, but no cigar.  There is an unwanted <code>xmlns="..."</code> attribute; it must not be present.  In my <code>XmlWriter</code>, I have done the following to remove the namespace unless found atop the object it is serializing:</p>
  
  <pre><code> protected override void OnWrite&lt;T&gt;(T sourceData, Stream outputStream)
      {
          IKnownTypesLocator knownTypesLocator = KnownTypesLocator.Instance;
  
          //Let's see if we can get the default namespace
          XmlRootAttribute xmlRootAttribute = sourceData.GetType().GetCustomAttributes&lt;XmlRootAttribute&gt;().FirstOrDefault();
  
          XmlSerializer serializer = null;
  
          if (xmlRootAttribute != null)
          {
              string nameSpace = xmlRootAttribute.Namespace ?? string.Empty;
              XmlSerializerNamespaces nameSpaces = new XmlSerializerNamespaces();
              nameSpaces.Add(string.Empty, nameSpace);
              serializer = new XmlSerializer(typeof(T), new XmlAttributeOverrides(), knownTypesLocator.XmlItems.ToArray(), xmlRootAttribute, nameSpace);
  
              //Now we can serialize
              using (StreamWriter writer = new StreamWriter(outputStream))
              {
                  serializer.Serialize(writer, sourceData, nameSpaces);
              }
          }
          else
          {
              serializer = new XmlSerializer(typeof(T), knownTypesLocator.XmlItems.ToArray());
  
              //Now we can serialize
              using (StreamWriter writer = new StreamWriter(outputStream))
              {
                  serializer.Serialize(writer, sourceData);
              }
          }
      }
  </code></pre>
  
  <p>I'm sure I'm overlooking something.  Any help would be greatly appreciated!</p>
  
  <p><strong>UPDATE 9/26/2017</strong>
  So... I've  been asked to provide more detail, specifically an explanation of the purpose of my code, and a reproducible example.  So here's both:</p>
  
  <ol>
  <li>The purpose for the XML.  I am writing an interface UI between two systems.  I read data from one, give users options to massage the data, and then give the the ability to export the data into files the second system can import.  It's regarding a bill of material system where system one are the CAD drawings and objects in those drawings and system two is an enterprise estimating system that is also being configured to support electronic bills of material.  I was given the XMLs from the vendor to recreate.</li>
  <li><p>Fully functional example code.... I've tried generalizing the code in a reproducible form.  </p>
  
  <pre><code>[XmlRoot("OutlTxt", Namespace = "http://www.mynamespace/09262017")]
  public class OutlineText
  {
      private string _value;
  
      [XmlElement("TextOutlTxt")]
      public XmlNode Value
      {
          get
          {
              string text = _value;
              text = Regex.Replace(text, @"[\a\b\f\n\r\t\v\\""'&amp;&lt;&gt;]", m =&gt; string.Join(string.Empty, m.Value.Select(c =&gt; string.Format("&amp;#x{0:X};", Convert.ToInt32(c))).ToArray()));
              string value = "\n&lt;p style=\"text-align:left;margin-top:0pt;margin-bottom:0pt;\"&gt;\n&lt;span&gt;ReplaceMe&lt;/span&gt;\n&lt;/p&gt;\n";
  
              XmlDocument document = new XmlDocument();
              document.InnerXml = "&lt;root&gt;" + value + "&lt;/root&gt;";
  
              XmlNode innerNode = document.DocumentElement.FirstChild;
              innerNode.InnerText = text;
  
              return innerNode;
           }
          set
          { }
      }
  
      private OutlineText()
      { }
  
      public OutlineText(string text)
      {
          _value = text;
      }
  
  }
  
   public class XmlFileWriter
  {
      public void Write&lt;T&gt;(T sourceData, FileInfo targetFile) where T : class
      {
          //This is actually retrieved through a locator object, but surely no one will mind an empty
          //collection for the sake of an example
          Type[] knownTypes = new Type[] { };
  
          using (FileStream targetStream = targetFile.OpenWrite())
          {
               //Let's see if we can get the default namespace
               XmlRootAttribute xmlRootAttribute = sourceData.GetType().GetCustomAttributes&lt;XmlRootAttribute&gt;().FirstOrDefault();
  
               XmlSerializer serializer = null;
  
              if (xmlRootAttribute != null)
              {
                   string nameSpace = xmlRootAttribute.Namespace ?? string.Empty;
                   XmlSerializerNamespaces nameSpaces = new XmlSerializerNamespaces();
                   nameSpaces.Add(string.Empty, nameSpace);
                   serializer = new XmlSerializer(typeof(T), new XmlAttributeOverrides(), knownTypes, xmlRootAttribute, nameSpace);
  
                   //Now we can serialize
                  using (StreamWriter writer = new StreamWriter(targetStream))
                  {
                       serializer.Serialize(writer, sourceData, nameSpaces);
                   }
              }
              else
              {
                  serializer = new XmlSerializer(typeof(T), knownTypes);
  
                  //Now we can serialize
                  using (StreamWriter writer = new StreamWriter(targetStream))
                  {
                      serializer.Serialize(writer, sourceData);
                  }
              }
          }
      }
  }
  
  
   public static void Main()
  {
      OutlineText outlineText = new OutlineText(@"SUBSTA SF6 CIRCUIT BKR CONC FDN ""C""");
  
      XmlFileWriter fileWriter = new XmlFileWriter();
      fileWriter.Write&lt;OutlineText&gt;(outlineText, new FileInfo(@"C:\MyDirectory\MyXml.xml"));
  
  
      Console.ReadLine();
  }
  </code></pre></li>
  </ol>
  
  <p>The result produced:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;OutlTxt xmlns="http://www.mynamespace/09262017"&gt;
    &lt;TextOutlTxt&gt;
      &lt;p style="text-align:left;margin-top:0pt;margin-bottom:0pt;" xmlns=""&gt;SUBSTA SF6 CIRCUIT BKR CONC FDN &amp;amp;#x22;C&amp;amp;#x22;&lt;/p&gt;
    &lt;/TextOutlTxt&gt;
  &lt;/OutlTxt&gt;
  </code></pre>
  
  <p><strong>Edit 9/27/2017</strong>
  Per the request in the solution below, a secondary issue I've ran into is keeping the hexadecimal codes.  To illustrate this issue based on the above example, let's say the value between  is </p>
  
  <p><code>SUBSTA SF6 CIRCUIT BKR CONC FDN "C"</code></p>
  
  <p>The vendor file is expecting the literals to be in their hex code format like so</p>
  
  <pre><code>SUBSTA SF6 CIRCUIT BKR CONC FDN &amp;#x22;C&amp;#x22;
  </code></pre>
  
  <p>I've rearranged the sample code Value property to be like so:</p>
  
  <pre><code>        private string _value;
  
      [XmlAnyElement("TextOutlTxt", Namespace = "http://www.mynamespace/09262017")]
      public XElement Value
      {
          get
          {
              string value = string.Format("&lt;p xmlns=\"{0}\" style=\"text-align:left;margin-top:0pt;margin-bottom:0pt;\"&gt;&lt;span&gt;{1}&lt;/span&gt;&lt;/p&gt;", "http://www.mynamespace/09262017", _value);
  
  
              string innerXml = string.Format("&lt;TextOutlTxt xmlns=\"{0}\"&gt;{1}&lt;/TextOutlTxt&gt;", "http://www.mynamespace/09262017", value);
  
              XElement element = XElement.Parse(innerXml);
  
              //Remove redundant xmlns attributes
              foreach (XElement descendant in element.DescendantsAndSelf())
              {
                  descendant.Attributes().Where(att =&gt; att.IsNamespaceDeclaration &amp;&amp; att.Value == "http://www.mynamespace/09262017").Remove();
              }
  
              return element;
          }
          set
          {
              _value = value == null ? null : value.ToString();
          }
      }
  </code></pre>
  
  <p>if I use the code </p>
  
  <pre><code> string text = Regex.Replace(element.Value, @"[\a\b\f\n\r\t\v\\""'&amp;&lt;&gt;]", m =&gt; string.Join(string.Empty, m.Value.Select(c =&gt; string.Format("&amp;#x{0:X};", Convert.ToInt32(c))).ToArray()));
  </code></pre>
  
  <p>to create the hex code values ahead of the XElement.Parse(), the XElement converts them back to their literal values.  If I try to set the XElement.Value directly after the XElement.Parse()(or through SetValue()), it changes the &#x22; to &amp;#x22;  Not only that, but it seems to mess with the element output and adds additional elements throwing it all out of whack.</p>
  
  <p><strong>Edit 9/27/2017 #2</strong> to clarify, the original implementation had a related problem, namely that the escaped text was re-escaped.  I.e. I was getting</p>
  
  <pre><code>SUBSTA SF6 CIRCUIT BKR CONC FDN &amp;amp;#x22;C&amp;amp;#x22;
  </code></pre>
  
  <p>But wanted </p>
  
  <pre><code>SUBSTA SF6 CIRCUIT BKR CONC FDN &amp;#x22;C&amp;#x22;
  </code></pre>