title: Clean XML serializing a hierarchical, recursive data structure
body: <p>I have this class:</p>
  
  <pre><code>[XmlRoot("menuItem")]
  public class MenuItem
  {
      [XmlAttribute("text")]
      public string Text { get; set; }
  
      [XmlAttribute("isLink")]
      public bool IsLink { get; set; }
  
      [XmlAttribute("url")]
      public string Url { get; set; }
  
      [XmlArray("items", IsNullable = true)]
      public List&lt;MenuItem&gt; Items { get; set; }
  }
  </code></pre>
  
  <p>Which defines a menu hierarchy. Now, on serializing this class, the output XML for a 3-level menu is:</p>
  
  <pre><code>&lt;menuItem xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  text="Tools" isLink="false"&gt;
    &lt;items&gt;
      &lt;MenuItem text="Market" isLink="false"&gt;
        &lt;items&gt;
          &lt;MenuItem text="Market Analyzer" isLink="true" url="/tools/market/analyzer"&gt;
            &lt;items xsi:nil="true" /&gt;
          &lt;/MenuItem&gt;
        &lt;/items&gt;
      &lt;/MenuItem&gt;
      &lt;MenuItem text="Banking" isLink="false"&gt;
        &lt;items&gt;
          &lt;MenuItem text="Purchase" isLink="true" url="/buy?type=good"&gt;
            &lt;items xsi:nil="true" /&gt;
          &lt;/MenuItem&gt;
        &lt;/items&gt;
      &lt;/MenuItem&gt;
      &lt;MenuItem text="General" isLink="false"&gt;
        &lt;items&gt;
          &lt;MenuItem text="Forecasts" isLink="true" url="/wheather-forcasts?city=la"&gt;
            &lt;items xsi:nil="true" /&gt;
          &lt;/MenuItem&gt;
        &lt;/items&gt;
      &lt;/MenuItem&gt;
    &lt;/items&gt;
  &lt;/menuItem&gt;
  </code></pre>
  
  <p>So, <code>MenuItem</code> is both the <strong>root</strong> and the <strong>child-element</strong>. As the root, it's serialized as <code>menuItem</code> with proper casing. However, as child elements, it's capitalization is not correct. How can I make the serializer create <code>menuItem</code> and not <code>MenuItem</code> in the output for child items. Case sensitivity matters to me here.</p>
  
  <p>I tried to put <code>[XmlElement]</code> attribute on the class itself, but got the following error:</p>
  
  <blockquote>
    <p>Attribute 'XmlArrayItem' is not valid on this declaration type. It is
    only valid on 'property, indexer, field, param, return' declarations.</p>
  </blockquote>
  
  <p>Also, I don't want those default namespaces there, and I don't want the child items to be created as empty elements. The ultimate XML file should be as clean as this XML example:</p>
  
  <pre><code>&lt;menuItem text='Tools' isLink='false'&gt;
    &lt;items&gt;
      &lt;menuItem text='Market' isLink='false'&gt;
        &lt;items&gt;
          &lt;menuItem text='Market Analyzer' isLink='true' url='/tools/market/analyzer' /&gt;
        &lt;/items&gt;
      &lt;/menuItem&gt;
      &lt;menuItem text='Banking' isLink='false'&gt;
        &lt;items&gt;
          &lt;menuItem text='Purchase' isLink='true' url='/buy?type=good' /&gt;
        &lt;/items&gt;
      &lt;/menuItem&gt;
      &lt;menuItem text='General' isLink='false'&gt;
        &lt;items&gt;
          &lt;menuItem text='Forecasts' isLink='true' url='/wheather-forcasts?city=la' /&gt;
        &lt;/items&gt;
      &lt;/menuItem&gt;
    &lt;/items&gt;
  &lt;/menuItem&gt;
  </code></pre>
  
  <p>What attributes should I use?</p>