Hi again.
I have implemented a solution using a DOM structure as i described above (the asXmlNode methods). But now i am thinking QXmlStreamWriter might be better. I just have one problem though; it's going to be hard to do it with class inheritance.
Currently i have the following class hierarchy, where each object would have a method to write itself on the XML stream.
class ObjectA {
// blah blah
virtual void toXmlStream(QXmlStreamWriter& stream);
};
class ObjectB : public ObjectA {
// blah blah
void toXmlStream(QXmlStreamWriter& stream);
};
class ObjectA {
// blah blah
virtual void toXmlStream(QXmlStreamWriter& stream);
};
class ObjectB : public ObjectA {
// blah blah
void toXmlStream(QXmlStreamWriter& stream);
};
To copy to clipboard, switch view to plain text mode
ObjectA would write it's element and child elements like so:
void ObjectA::toXmlStream(QXmlStreamWriter& stream) {
stream.writeStartElement("ObjectA");
stream.writeStartElement("variable1");
stream.writeTextElement(variable1);
stream.writeEndElement();
// more child elements ...
stream.writeEndElement(); // end of "ObjectA" element
}
// And elsewhere, write the xml to a file
QXmlStreamWriter stream(&file);
stream.writeStartDocument();
object->toXmlStream(stream);
stream.writeEndDocument();
void ObjectA::toXmlStream(QXmlStreamWriter& stream) {
stream.writeStartElement("ObjectA");
stream.writeStartElement("variable1");
stream.writeTextElement(variable1);
stream.writeEndElement();
// more child elements ...
stream.writeEndElement(); // end of "ObjectA" element
}
// And elsewhere, write the xml to a file
QXmlStreamWriter stream(&file);
stream.writeStartDocument();
object->toXmlStream(stream);
stream.writeEndDocument();
To copy to clipboard, switch view to plain text mode
But then what happens when ObjectB overrides that method with the intent of extending it:
void ObjectB::toXmlStream(QXmlStreamWriter& stream) {
ObjectA::toXmlStream(stream);
// Oops, super class has just written the end of it's main element...
// the elements below will be orphaned
stream.writeStartElement("variable2");
stream.writeTextElement(variable2);
stream.writeEndElement();
// more of ObjectB's child elements ...
}
void ObjectB::toXmlStream(QXmlStreamWriter& stream) {
ObjectA::toXmlStream(stream);
// Oops, super class has just written the end of it's main element...
// the elements below will be orphaned
stream.writeStartElement("variable2");
stream.writeTextElement(variable2);
stream.writeEndElement();
// more of ObjectB's child elements ...
}
To copy to clipboard, switch view to plain text mode
The solution is to write the objects "main" element before the object's toXmlStream method is called:
QXmlStreamWriter stream(&file);
stream.writeStartDocument();
stream.writeStartElement("ObjectA");
objectB->toXmlStream(stream);
stream.writeEndElement();
stream.writeEndDocument();
QXmlStreamWriter stream(&file);
stream.writeStartDocument();
stream.writeStartElement("ObjectA");
objectB->toXmlStream(stream);
stream.writeEndElement();
stream.writeEndDocument();
To copy to clipboard, switch view to plain text mode
And ObjectA::toXmlStream would not write it's own "ObjectA" element.
But this just seems ugly. It would mean that the method writing the object would need to know something about that object. And i would have to ensure i consistently write the same element where ever i write that object to the xml stream.
Is this how it has to be? In which case, i will go back to using the DOM way. Or is there a neat/simple way around this problem.
Bookmarks