title: XmlSerializer: serializing a class property as an attribute of a custom subelement
body: <p>I'm using an <code>XmlSerializer</code>. My class:</p>
  
  <pre><code>[Serializable]
  [XmlRoot(ElementName="MyClass")]
  public class MyClass
  {
      public string Value;
  }
  </code></pre>
  
  <p>I would like to serialize it so that <code>Value</code> ends up as an attribute of a subelement named (for instance) "Text".</p>
  
  <p><strong>Desired outcome:</strong></p>
  
  <pre><code>&lt;MyClass&gt;
      &lt;Text Value="3"/&gt;
  &lt;/MyClass&gt;
  </code></pre>
  
  <p>But <strong>NOT</strong> (which would be the effect of marking Value as an <code>XmlAttribute</code>)</p>
  
  <pre><code>&lt;MyClass Value="3"&gt;
  &lt;/MyClass&gt;
  </code></pre>
  
  <p>And <strong>NOT</strong> (which would be the effect of marking Value as an <code>XmlElement</code>):</p>
  
  <pre><code>&lt;MyClass&gt;
      &lt;Value&gt;3&lt;/Value&gt;
  &lt;/MyClass&gt;
  </code></pre>
  
  <p>How do I achieve this?</p>
  
  <p><strong>I am aware that I could change the type of <code>Value</code> from string to another serializable custom class.</strong> </p>
  
  <p>Unfortunately, I have plenty of such properties, so I'd need to create dozens of tiny classes.</p>
  
  <p>Is there any quicker solution? </p>
  
  <hr>
  
  <p><strong>EDIT:</strong></p>
  
  <p>In response to your comments:</p>
  
  <ul>
  <li><p>No, not every property has to be serialized to a subelement named "Text". Subelement's name is unique and unambiguous.</p></li>
  <li><p>Sample output XML:</p>
  
  <pre><code>&lt;visibility&gt;
      &lt;site visible="yes"/&gt;
      &lt;comparator visible="no"/&gt;
      &lt;expiration days="7"/&gt;
      &lt;comment&gt;blahblahblah&lt;/comment&gt;
  &lt;visibility&gt;
  </code></pre></li>
  <li><p>Sample class:</p></li>
  </ul>
  
  <p>!</p>
  
  <pre><code>[XmlRoot(ElementName="Visibility")]
  public class Visibility
  {
      [XPath("/site@visible")] // if only this was possible!
      public string OnSite
      {
          get { return SiteVisible ? "yes" : "no"; }
      }
  
      [XPath("/comparator@visible")] // as above...
      public string InComparator
      {
          get { return ComparatorVisible ? "yes" : "no"; }
      }
  
      [XmlIgnore]
      public bool SiteVisible;
      [XmlIgnore]
      public bool ComparatorVisible;
  
      [XPath("/expiration@days")] // as above...
      public int ExpiresAfterDays; 
  
      [XmlElement("comment")] // this is easy
      public string Comment;
  }
  </code></pre>