Objects stored in the XML file can be loaded back by using the function wxXmlSerializer::DeserializeFromXml(const wxString &file)
where parameter file means the path to the input XML file. The function returns true value whether the objects was succesfully deserialized.
Next steps depends on that how the objects have been added to the serializer during their serialization. These different methods of access to the deserialized objects are described by the samples in this topic. All samples use the serializable class from the previous topic Creation of the serializable class.
Objects stored in the XML file as the root node can be restored in two simple steps:
insert the serializable class instance which we want restore to the serializer as its root node
deserialize the XML file by using the function wxXmlSerializer::DeserializeFromXml
Restored data in serializable class can now be accessed via class members as can been seen in following example where the values will be loaded from this XML file:
<?xml version="1.0" encoding="utf-8"?> <object owner="Example" version="1.0.0"> <object_properties> <object type="SerializableObject"> <property name="id" type="long">-1</property> <property name="wxStringProperty" type="string">Values loaded from XML file.</property> <property name="wxPointProperty" type="point">25,50</property> <property name="IntegerProperty" type="int">16</property> </object> </object_properties> </object>
void PrintMembers(SerializableObject *obj)
{
wxPrintf(obj->m_wxStringProperty << wxT("\n"));
wxPrintf(wxT("%d, %d\n"), (obj->m_wxPointProperty).x, (obj->m_wxPointProperty).y);
wxPrintf(wxT("%d\n\n"), obj->m_IntegerProperty);
}
int main( int argc, char ** argv )
{
// create the serializer
wxXmlSerializer serializer;
// initialize the serializer
serializer.SetSerializerOwner(wxT("Example"));
serializer.SetSerializerRootName(wxT("object"));
serializer.SetSerializerVersion(wxT("1.0.0"));
// create SerializableObject class instance with its default values
SerializableObject *pObject= new SerializableObject();
// print object's members with their default values
wxPrintf(wxT("Data members of 'pObject' with their default values:\n"));
PrintMembers(pObject);
// add the object to the serializer as its root node
serializer.SetRootItem(pObject);
// load object's members values from XML file
if(wxFileExists(wxT("data.xml")))
{
serializer.DeserializeFromXml(wxT("data.xml"));
}
// print object's members with values loaded from XML file
wxPrintf(wxT("Data members of 'pObject' with values loaded from XML file:\n"));
PrintMembers(pObject);
wxPrintf(wxT("Press ENTER to exit...\n"));
while(wxFgetc(stdin) != '\n');
}
For succesfull deserialization the serializer must be initialized to same values like in XML file.
After successful deserialization the stored class instances can be accessed by set of member functions declared in xsSerializable class:
xsSerializable::GetParent
- returns the object's parrent, if not exists returns NULL
xsSerializable::GetFirstChild
- returns the object's first child, if not exists returns NULL
xsSerializable::GetLastChild
- returns the object's last child, if not exists returns NULL
xsSerializable::GetSibbling
- returns the object's next sibbling, if not exists returns NULL
Following example demonstrates how to restore and access a list of objects:
void PrintMembers(SerializableObject *obj)
{
wxPrintf(obj->m_wxStringProperty << wxT("\n"));
wxPrintf(wxT("%d, %d\n"), (obj->m_wxPointProperty).x, (obj->m_wxPointProperty).y);
wxPrintf(wxT("%d\n\n"), obj->m_IntegerProperty);
}
int main( int argc, char ** argv )
{
// create the serializer
wxXmlSerializer serializer;
// load object's members values from XML file
if(wxFileExists(wxT("data.xml")))
{
serializer.DeserializeFromXml(wxT("data.xml"));
}
// get pointer to the first serialized object
SerializableObject *pObject = (SerializableObject*)serializer.GetRootItem()->GetFirstChild();
while(pObject)
{
PrintMembers(pObject);
// get next serialized object, pObject will be NULL if the object doesn't exist
pObject = (SerializableObject*) ((xsSerializable*)pObject)->GetSibbling();
}
wxPrintf(wxT("Press ENTER to exit...\n"));
while(wxFgetc(stdin) != '\n');
}
An output of this sample application:
This modified sample demonstrates how to restore and access objects arranged in the tree structure:
void PrintTree( xsSerializable *parent, int level )
{
level++;
wxString spaces = wxT("");
// get the children of given parent
SerializableObject *pObject = (SerializableObject*)parent->GetFirstChild();
while( pObject )
{
// print info about data members of current object...
for( int i = 1; i < level; i++ )
spaces += wxT(" ");
wxPrintf(spaces);
wxPrintf(pObject->m_wxStringProperty << wxT("\n"));
wxPrintf(spaces);
wxPrintf(wxT("%d, %d\n"), (pObject->m_wxPointProperty).x, (pObject->m_wxPointProperty).y);
wxPrintf(spaces);
wxPrintf(wxT("%d\n"), pObject->m_IntegerProperty);
// .. and process the object's children if exist
if( pObject->HasChildren() ) PrintTree( pObject, level );
// get sibbling of the current object
pObject = (SerializableObject*)pObject->GetSibbling();
}
}
int main( int argc, char ** argv )
{
// create instance of wxXmlSerializer
wxXmlSerializer serializer;
// relooad stored objects from XML file
serializer.DeserializeFromXml( wxT("data.xml") );
// print out info about loaded class instances
PrintTree( serializer.GetRootItem(), 0 );
wxPrintf( wxT("\nPress ENTER to exit...\n") ); while( wxFgetc( stdin ) != '\n' );
}
In this sample the objects in a tree structure is browsed by recurently calling
the function PrintTree
.
An output of the application created from the source code above will look like this: