PDA

View Full Version : Using the same QXmlStreamReader across multiple classes to read a single XML file



duckman
1st April 2010, 00:10
Hey all,

First, if there is a post that I missed in my search that talks about doing this please give me the link and I'd be happy to look at the post for the suggestions. :)

I have some XML files I am reading into objects and in order to split up the code into logical pieces I split up the XML readers across multiple classes as such:

BaseXmlReader Class - A superclass of Class1XmlReader and Class2XmlReader. It contains some general functions that QXmlStreamReader doesn't provide that Class1XmlReader and Class2XmlReader both use, so Class1XmlReader and Class2XmlReader inherit from it.

Class1 - Contains data. If I want to read Class1 data that is in XML I have a Class1XmlReader that has QXmlStreamReader and Class1 as members. The Class1XmlReader uses the QXmlStreamReader to read the XML data and then set the Class1 members appropriately via Class1's public functions.

Class2 - Contains data. Class2 also has a Class2XmlReader to read in its XML data from a file. Class2XmlReader has QXmlStreamReader and Class2 members as well. It sets Class2 data via Class2's public functions with the XML data it read.

Now, Class1 contains a list of Class2 instances as a member, so I want to be able to read in a Class1 XML file that contains Class2 XML data and Class1 xml data as such:

<class1>


<name>Qt Rocks</name>
<class1_element>Data here</class1_element>
<class2>

<class2_data>Data here</class2_data>
</class2>
<class2>

<class2_data>Data here too!</class2_data>
</class2>

</class2>

What I am doing is using the Class1XmlReader's QXmlStreamReader to read in an XML file and set Class1's members correctly, but when I get to the <class2> tags I create an instance of the Class2XmlReader to take over and read the Class2 data. After the Class2XmlReader reads and converts the data into a Class2 object I can then request the completed Class2 object from the Class2XmlReader and add it to the list in an instance of Class1 contained in Class1XmlReader.

My goal is to pass on Class1XmlReader's QXmlStreamReader onto Class2XmlReader in the same state and at the same spot in the file where I left off. So.. I have attempted to do a setDevice() in Class2XmlReader using the device pointer from Class1XmlReader but I receive an Invalid token when I attempt a readNext() from within Class2XmlReader. I also attempted to copy Class2XmlReader's QXmlStreamReader instance and give it to Class2XmlReader, but QXmlStreamReader doesn't have a public copy constructor. It also doesn't have a protected copy constructor so Class1XmlReader and Class2XmlReader can't inherit from QXmlStreamReader to use it.

Class1XmlReader and Class2XmlReader have Class1 and Class2 as members to set the data when found in the XML file, but they are not subclasses of Class1 and Class2, respectively. Class1 and Class2 can be retrieved from Class1XmlReader and Class2XmlReader by public calls in Class1XmlReader and Class2XmlReader when the parsing is complete.

Since the setDevice() and copy constructor method seem to be out I was thinking I could just have a private function inside of the BaseXmlReader class called setXmlReader(QXmlStreamReader* xmlReader). The setXmlReader() function would pass along the state of Class1XmlReader's QXmlStreamReader before passing control to Class2XmlReader to read its part of the XML file that it understands. Of course, Class2XmlReader wouldn't delete, and would have to remember it isn't the owner of, the xmlReader it was given by Class1XmlReader. This should pass on the state correctly, but I was wondering other methods I may be overlooking.

Any thoughts? How does everyone else pass QXmlStreamReader on to the next XML reader and still keep the QXmlStreamReader in the same state to continue reading in the same file? Hopefully I clearly explained what I am trying to do. If not, I'd be happy to explain further.

Thanks!

- Donald

axeljaeger
3rd April 2010, 16:52
You want to create a "hierarchical parser", is that correct? You see XML as a tree and you want to have two subtrees parsed by a different parser?

duckman
3rd April 2010, 20:07
You want to create a "hierarchical parser", is that correct? You see XML as a tree and you want to have two subtrees parsed by a different parser?

Correct. How I have it setup now is BaseXmlReader has a constructor that accepts a pointer to a QXmlStreamReader. It then uses that as the reader instead of creating a new instance like it would with other constructors. It keeps track if it was given another QXmlStreamReader or it created it's own on construction, so at destruction it doesn't delete the QXmlStreamReader it was given from a parent reader.

Archimedes
3rd April 2010, 21:35
What if you make a singleton class containing the QXmlStreamReader or maybe use the visitor pattern?