[quoted text, click to view] Todd wrote:
> I'm developing an application that accepts XML input from a diverse set of
> clients. Some clients specify values as an attribute, and some specify values
> as a sub-element.
>
> The XmlSerializer doesn't seem to handle both cases (attribute vs. element)
> by default. Is there a way to get the Deserializer to recognizer EITHER
> attribute or element for the same class?
>
No, there isn't. In general, the XmlSerializer works best when there's one
single format that's tightly coupled to the class. This is most compatible
with the attributed model the serializer uses. If you need to deserialize
from heterogeneous sources, you can either write the deserialization logic
yourself (with simple classes like XPathNavigator), or you can use multiple
distinct serialization classes decoupled from the actual data object, or you
can use overrides, or you can modify your class (which is easiest, but tends
to get ugly).
Here's an example of modifying the class:
[Serializable]
public class Person {
[XmlAttribute(AttributeName = "sex")]
public string SexAttribute;
[XmlElement(ElementName = "sex")]
public string SexElement;
public string Sex {
get { return SexElement ?? SexAttribute; }
}
public string FirstName;
public string LastName;
}
This also illustrates another problem: if you want to serialize this class,
you have to decide whether the "sex" field will be serialized as an element
or as an attribute, so it makes sense that these end up as separate properties.
Here's how we can do the same thing with overrides:
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attributes = new XmlAttributes();
attributes.XmlAttribute = new XmlAttributeAttribute();
overrides.Add(typeof(person), "sex", attributes); // Serialize "sex" as an
attribute instead of an element
XmlSerializer mySerializer = new XmlSerializer(typeof(person), overrides);
Obviously, this solution doesn't work unless you know what format your
client will use in advance. The same objection applies to any solution that
uses XmlSerializer for deserialization, however.
[quoted text, click to view] > According to the standard XML spec, specifying a value as either an element
> or an attributes should be identical.
>
This is not true, or rather, you're misinterpreting it. An attribute is
*not* equivalent to a child element. They are equivalent insofar as they
allow for the same semantics, but they are not treated as the same thing.
You'll find that almost everything based on XML makes a clear distinction
between them. Unfortunately, this does lead to endless "attribute or
element" discussions that are often pointless.
It's by far better to specify which one you're going to use and stick to it
then to allow clients to pass whatever they want.
--