all groups > dotnet xml > may 2004 >
You're in the

dotnet xml

group:

Serializing array of userdefined types



Serializing array of userdefined types Lidström
5/19/2004 12:09:36 PM
dotnet xml: Hello,

I want to have a class that contains only a collection of another class.
For example:

public __gc class Alignment {
public:
Alignment();
...
};

// Probably using XmlIncludeAttribute such as this is wrong...
[System::Xml::Serialization::XmlIncludeAttribute(__typeof(Alignment))]
public __gc class Alignments : public System::Collections::ArrayList {
public:
Alignments();
...
};

I figured I could use Alignments like this:
Alignment* alignment = new Alignment;
Alignments* alignments = new Alignments;
alignments->Add(alignment);

BTW, I am using XmlSerializer and XmlTextWriter.

But I get exceptions:
--------- Exception Data ---------
Message: There was an error reflecting type 'LX.LandXML'.
Exception Type: System.InvalidOperationException
Source: System.Xml
StrackTrace: at
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel
model, String ns, ImportContext context, String dataType, Boolean repeats)
at
System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel
model, XmlRootAttribute root, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String
defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type)
at main(Int32 argc, SByte** argv) in c:\documents and
settings\daniel.sbg\my documents\visual studio
projects\managed_test\test1\test1.cpp:line 22
TargetSite: System.Xml.Serialization.TypeMapping
ImportTypeMapping(System.Xml.Serialization.TypeModel, System.String,
ImportContext, System.String, Boolean)
--------- Exception Data ---------
Message: There was an error reflecting property 'Alignments'.
Exception Type: System.InvalidOperationException
Source: System.Xml
StrackTrace: at
System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel
model, String ns)
at
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel
model, String ns, ImportContext context, String dataType, Boolean repeats)
TargetSite: System.Xml.Serialization.StructMapping
ImportStructLikeMapping(System.Xml.Serialization.StructModel,
System.String)


What is the usual way to serialize a collection of the same type of
objects? The end result I am after is this:
<Alignments>
<Alignment name="Centreline>
</Alignment>
<Alignment name="LeftCatch">
</Alignment>
... arbitrary number of Alignments
</Alignments>

Any pointers or references very much appreciated.
Thanks!

--
Re: Serializing array of userdefined types Alex Shirshov
5/20/2004 12:39:27 PM
Hello, Daniel!
You wrote on Wed, 19 May 2004 12:09:36 +0200:


[Sorry, skipped]


DL> What is the usual way to serialize a collection of the same type of
DL> objects? The end result I am after is this:
DL> <Alignments>
DL> <Alignment name="Centreline>
DL> </Alignment>
DL> <Alignment name="LeftCatch">
DL> </Alignment>
DL> ... arbitrary number of Alignments
DL> </Alignments>

DL> Any pointers or references very much appreciated.
DL> Thanks!

Well, maybe this example be right for you.
[code]
#using <mscorlib.dll>
#using <System.Xml.dll>

using namespace System;
using namespace System::Collections;
using namespace System::Xml;
using namespace System::Xml::Serialization;
using namespace System::IO;

public __gc class foo
{
public:
foo()
{
}

foo(System::String* s)
{
_s = s;
}
public:
[XmlAttributeAttribute(S"name")]
System::String* _s;
};

public __gc class foos
{
public:
foos()
{
arr = new ArrayList();
}
public:
[XmlArray(S"Alignments")]
[XmlArrayItemAttribute(S"Alignment",__typeof(foo))]
ArrayList* arr;
};

int _tmain()
{
XmlSerializer* xs = new XmlSerializer(__typeof(foo));
foo* f = new foo(S"hi!");
Text::StringBuilder* sb = new Text::StringBuilder();
StringWriter* sw = new StringWriter(sb);
xs->Serialize(sw,f);
sb->Append(S"\n-------\n");
foos* fs = new foos();
fs->arr->Add(f);
xs = new XmlSerializer(__typeof(foos));
xs->Serialize(sw,fs);
Console::WriteLine(sb->ToString());
return 0;
}
[/code]

With best regards, Alex Shirshov.

Re: Serializing array of userdefined types Lidström
5/24/2004 11:17:14 AM
[quoted text, click to view]

[...]

[quoted text, click to view]

Thanks a lot Alex! This is just what I needed.

--
Re: Serializing array of userdefined types Lidström
5/24/2004 4:05:13 PM
[quoted text, click to view]

[...]

[quoted text, click to view]

New problem: The end result I am after is this:
<Alignments name="Road Project">
<Alignment name="Centerline" />
<Alignment name="Centerline 2" />
... arbitrary number of these
</Alignments>

What I get right now is this:
<Alignments name="Road Project">
<Alignment>
<Alignment name="Centerline" />
<Alignment name="Centerline 2" />
</Alignment>
</Alignments>

I am doing it this way (everything is in namespace LX):

public __gc class LandXML {
public:
LandXML() { }

__property LX::Alignments* get_Alignments() { return m_arr; }
__property void set_Alignments(LX::Alignments* a) { m_arr = a; }

protected:

LX::Alignments* m_arr;

};

public __gc class Alignment {
public:
Alignment() { }
[XmlAttributeAttribute("name")]
__property String* get_name() { return m_name; }
__property void set_name(String* n) { m_name = n; }

protected:
String* m_name;
};

public __gc class Alignments {
public:
Alignments() { m_array = new ArrayList(); }

[XmlAttributeAttribute("name")]
__property System::String* get_name() { return m_name; }
__property void set_name(System::String* n) { m_name = n; }

[XmlArrayItemAttribute(Type=__typeof(LX::Alignment))]
__property ArrayList* get_Alignment() { return m_array; }
__property void set_Alignment(ArrayList* arr) { m_array = arr; }

void Add(LX::Alignment* alignment) { m_array->Add(alignment); }

protected:

String* m_name;
ArrayList* m_array;

};


Somewhere in main.cpp I set the elements of a LandXml object, and serialize
object to disk:

XmlSerializer* ser = new XmlSerializer(__typeof(LandXML));
XmlTextWriter* writer = new XmlTextWriter("out.xml", Encoding::UTF8);
// write a human readable file
writer->Formatting = Formatting::Indented;
LandXML* land_xml = new LandXML();
Alignment* alignment = new Alignment;
Alignment* alignment2 = new Alignment;
alignment->name = "Centerline";
alignment2->name = "Centerline 2";
land_xml->Alignments->Add(alignment);
land_xml->Alignments->Add(alignment2);
land_xml->Alignments->name = "Road Project";
ser->Serialize(writer, land_xml);
writer->Close();


So it seems I need to remove one level of Alignment, only I don't really
know how to do it. If I create a class Alignment that instead of having a
ArrayList as member, I let it inherit from ArrayList. Then it doesn't
matter if I have a attribute called name, because it will not be
serialized. How can I solve this problem? Any help in form of samples,
links, docs, very much appreciated.
Thanks!

--
AddThis Social Bookmark Button