1

I want to use XmlSerializer to serialize a class, typical stuff. My ONE difference is I want to serialize a custom object "ComplexType" as as attribute, not a child element.

I've seen other stack overflow questions and the answers say it's not possible. I know that's wrong.

The error is like:

"XmlAttribute/XmlText can not be used to encode complex types."

--or--

"XmlAttribute/XmlText can not be used to encode types implementing IXmlSerializable."

Simply change myfield from ComplexType to DateTime and it works fine. DateTime is definitely complex, so I just need to know what to change in the class or attributes.

ex: YES

<Container myComplexType="specialencoding" />

ex: NO

<Container>
   <myComplexType>specialencoding</myComplexType>
</Container>

-- See how much nicer the first one is... I want that one.

-- Code is like this...

[XmlRoot(ElementName="Container")]
public class Container
{
  [XmlAttribute(AttributeName="myComplexType")]
  public ComplexType myfield = new ComplexType();
}


public class ComplexType
{
    public ComplexType(){}
    public ComplexType(string encoding){}
    public override string ToString() {return "specialencoding";}
}

If I implement ComplexType : IXmlSerializable, I get the second error message above.

Basic serializer used:

XmlSerializer serializer = new XmlSerializer(typeof(Container));
serializer.serialize("outfile.xml", new Container());
extracrispy
  • 669
  • 5
  • 16
  • The Xml Attribute is a string. When you make the XmlAttribute a DateTime is becomes a string with double quotes. If it was complex then there would not be quotes around the DateTime. – jdweng Dec 06 '18 at 19:22
  • Right, I can convert my type to/from a simple string so I'd like to be able to behave like DateTime and write to an attribute - with quotes. – extracrispy Dec 06 '18 at 19:27
  • *I've seen other stack overflow questions and the answers say it's not possible. I know that's wrong.* - can you share the answers that didn't meet your requirements, so we don't duplicate effort? – dbc Dec 06 '18 at 19:56
  • The schema type xs:dateTime is a simple type, not a complex type. A complex type in XSD is one that contains elements as well as character content. Simply having an internal microsyntax does not make it complex. – Michael Kay Dec 06 '18 at 20:17

1 Answers1

-1

Try this :

        private ComplexType _myfield = new ComplexType();

        [XmlAttribute(AttributeName = "myComplexType")]
        public string myfield {
            get { return _myfield.ToString();}
        }
    }
    public class ComplexType
    {
        public ComplexType(){}
        public ComplexType(string encoding){}
        public override string ToString() {return "specialencoding";}
    }
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • Right, that was the answer in the other questions. If I've got a bunch of attributes, I don't want to have to do 2x the code, and the same goes for adding/removing fields. DateTime can do it just fine, so what's going on with it? – extracrispy Dec 06 '18 at 19:46
  • To be serialized by `XmlSerializer`, the property `myfield` must be read/write. – dbc Dec 06 '18 at 19:50
  • @extracrispy - from the [docs](https://docs.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlattributeattribute?view=netframework-4.7.2#remarks): *You can assign the XmlAttributeAttribute only to public fields or public properties that return a value (or array of values) that can be mapped to one of the XML Schema definition language (XSD) simple types ... See the [`DataType`](https://docs.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlattributeattribute.datatype?view=netframework-4.7.2) property for a list of XSD types and how they are mapped to.NET data types.* – dbc Dec 06 '18 at 19:52
  • @extracrispy - and from the docs from [`XmlAttributeAttribute.DataType`](https://learn.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlattributeattribute.datatype?view=netframework-4.7.2#remarks), only known .Net primitives get mapped to XSD simple data types. Mapping an arbitrary type by using its `ToString()` is not documented to be implemented. – dbc Dec 06 '18 at 19:54
  • @dbc Oh, "XSD" simple types. I misread the original docs and thought it was C# simple / primitive types. Wow, ok. Maybe there is some way to accomplish it anyway with some implicit conversion operators? – extracrispy Dec 06 '18 at 20:08
  • @extracrispy - don't think so, the trick from [Most elegant XML serialization of Color structure](https://stackoverflow.com/a/4322461/3744182) doesn't seem to work, see https://dotnetfiddle.net/0rT1Sm – dbc Dec 06 '18 at 20:21
  • You do not need the ComplexType class. You can put all the code into the get/set public property and add any additional variables as private in the main class provided your XmlAttribute is a string. – jdweng Dec 07 '18 at 09:45