By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,052 Members | 1,248 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,052 IT Pros & Developers. It's quick & easy.

XML Serialization of complex types as XML attributes

P: n/a
Hi all

..NET Framework 1.1

I have created several types that are serailized to XML as strings. Someting
like this:

public struct MyInt32 : IXmlSerializable
{
int value;

public MyInt32(int value)
{
this.value = value;
}

public static implicit operator Int32(MyInt32 value)
{
return value.value;
}

public static implicit operator MyInt32(Int32 value)
{
return new MyInt32(value);
}

public static MyInt32 Parse(string str)
{
return int.Parse(str);
}

public static bool TryParse(string str, out MyInt32 value)
{
try
{
value = int.Parse(str);
return true;
}
catch
{
value = 0;
return false;
}
}

XmlSchema IXmlSerializable.GetSchema()
{
return null;
}

void IXmlSerializable.WriteXml(XmlWriter writer)
{
writer.WriteString(XmlConvert.ToString(this.value) );
}

void IXmlSerializable.ReadXml(XmlReader reader)
{
this.value = XmlConvert.ToInt32(reader.ReadString());
}

}

The XML serialization as a XML element works without any problems:

class MyClass
{
[XmlElement("v")]
public MyInt32 myValue;
}

But when I mark myValue with the XmlAttributeAttribute:

class MyClass
{
[XmlAttribute("v")]
public MyInt32 myValue;
}

I get:

System.InvalidOperationException: There was an error reflecting type
'ConsoleApplication.DTO'. ---> System.InvalidOperationException: There was an
error reflecting field 'v'. ---> System.InvalidOperationException: Cannot
serialize member 'v'. XmlAttribute/XmlText cannot be used to encode complex
types.
at
System.Xml.Serialization.XmlReflectionImporter.Imp ortAccessorMapping(MemberMapping
accessor, FieldModel model, XmlAttributes a, String ns, Type
choiceIdentifierType)
at
System.Xml.Serialization.XmlReflectionImporter.Imp ortFieldMapping(StructModel
parent, FieldModel model, XmlAttributes a, String ns)
at
System.Xml.Serialization.XmlReflectionImporter.Imp ortStructLikeMapping(StructModel model, String ns)
--- End of inner exception stack trace ---
at
System.Xml.Serialization.XmlReflectionImporter.Imp ortStructLikeMapping(StructModel model, String ns)
at
System.Xml.Serialization.XmlReflectionImporter.Imp ortTypeMapping(TypeModel
model, String ns, ImportContext context, String dataType, Boolean repeats)
--- End of inner exception stack trace ---
at
System.Xml.Serialization.XmlReflectionImporter.Imp ortTypeMapping(TypeModel
model, String ns, ImportContext context, String dataType, Boolean repeats)
at System.Xml.Serialization.XmlReflectionImporter.Imp ortElement(TypeModel
model, XmlRootAttribute root, String defaultNamespace)
at System.Xml.Serialization.XmlReflectionImporter.Imp ortTypeMapping(Type
type, XmlRootAttribute root, String defaultNamespace)
at System.Xml.Serialization.XmlReflectionImporter.Imp ortTypeMapping(Type
type)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String
defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type)
at ConsoleApplication.Program.Main()

How can I serialize MyType as a XML attribute?

--
Paulo Morgado

Jan 23 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a
The XmlSerializer doesn't know that your IXmlSerializable just calls
WriteString. What if you called WriteElementString instead? So the right
way to do this is expose a string Property

[XmlIgnore]
public MyInt32 MyValue;

[XmlAttribute("v")]
public string myValue {
get { return MyValue.ToString(); }
set { MyValue = MyInt32.Parse(value); }
}

"Paulo Morgado [MVP]" <pa***********@community.nospam> wrote in message
news:69**********************************@microsof t.com...
Hi all

.NET Framework 1.1

I have created several types that are serailized to XML as strings.
Someting
like this:

public struct MyInt32 : IXmlSerializable
{
int value;

public MyInt32(int value)
{
this.value = value;
}

public static implicit operator Int32(MyInt32 value)
{
return value.value;
}

public static implicit operator MyInt32(Int32 value)
{
return new MyInt32(value);
}

public static MyInt32 Parse(string str)
{
return int.Parse(str);
}

public static bool TryParse(string str, out MyInt32 value)
{
try
{
value = int.Parse(str);
return true;
}
catch
{
value = 0;
return false;
}
}

XmlSchema IXmlSerializable.GetSchema()
{
return null;
}

void IXmlSerializable.WriteXml(XmlWriter writer)
{
writer.WriteString(XmlConvert.ToString(this.value) );
}

void IXmlSerializable.ReadXml(XmlReader reader)
{
this.value = XmlConvert.ToInt32(reader.ReadString());
}

}

The XML serialization as a XML element works without any problems:

class MyClass
{
[XmlElement("v")]
public MyInt32 myValue;
}

But when I mark myValue with the XmlAttributeAttribute:

class MyClass
{
[XmlAttribute("v")]
public MyInt32 myValue;
}

I get:

System.InvalidOperationException: There was an error reflecting type
'ConsoleApplication.DTO'. ---> System.InvalidOperationException: There was
an
error reflecting field 'v'. ---> System.InvalidOperationException: Cannot
serialize member 'v'. XmlAttribute/XmlText cannot be used to encode
complex
types.
at
System.Xml.Serialization.XmlReflectionImporter.Imp ortAccessorMapping(MemberMapping
accessor, FieldModel model, XmlAttributes a, String ns, Type
choiceIdentifierType)
at
System.Xml.Serialization.XmlReflectionImporter.Imp ortFieldMapping(StructModel
parent, FieldModel model, XmlAttributes a, String ns)
at
System.Xml.Serialization.XmlReflectionImporter.Imp ortStructLikeMapping(StructModel
model, String ns)
--- End of inner exception stack trace ---
at
System.Xml.Serialization.XmlReflectionImporter.Imp ortStructLikeMapping(StructModel
model, String ns)
at
System.Xml.Serialization.XmlReflectionImporter.Imp ortTypeMapping(TypeModel
model, String ns, ImportContext context, String dataType, Boolean repeats)
--- End of inner exception stack trace ---
at
System.Xml.Serialization.XmlReflectionImporter.Imp ortTypeMapping(TypeModel
model, String ns, ImportContext context, String dataType, Boolean repeats)
at
System.Xml.Serialization.XmlReflectionImporter.Imp ortElement(TypeModel
model, XmlRootAttribute root, String defaultNamespace)
at System.Xml.Serialization.XmlReflectionImporter.Imp ortTypeMapping(Type
type, XmlRootAttribute root, String defaultNamespace)
at System.Xml.Serialization.XmlReflectionImporter.Imp ortTypeMapping(Type
type)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String
defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type)
at ConsoleApplication.Program.Main()

How can I serialize MyType as a XML attribute?

--
Paulo Morgado

Jan 24 '06 #2

P: n/a
Hi Chris. Thanks for your reply.

There are two things wrong in your approach to the problem:

1. Parse and ToString, at least in the way you showed, are all about
presentation and are culture dependente. XmlConvert should have been used,
but it's not extensible either.

2. You are not serializing MyValue and you are creating a new property that
I don't want my classes to have. I should have told that I already came to
this conclusion and also added an Obsolete attribute to warn developers not
to use that property.

I can understand that the XmlSerializer doesn't know how i will serialize my
type. There should be a IXmlSerilizableSomething to serialize the type as
just a string and the XmlSerializer should handle it. Another way to do it
would be to let the XmlReader/XmlWriter to handle if proper XML was being
read/written.

--
Paulo Morgado

"Chris Lovett" wrote:
The XmlSerializer doesn't know that your IXmlSerializable just calls
WriteString. What if you called WriteElementString instead? So the right
way to do this is expose a string Property

[XmlIgnore]
public MyInt32 MyValue;

[XmlAttribute("v")]
public string myValue {
get { return MyValue.ToString(); }
set { MyValue = MyInt32.Parse(value); }
}


Jan 24 '06 #3

P: n/a
Hi Chris,

Seems like I dumped my frustration on you. Sorry.

--
Paulo Morgado

Jan 24 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.