tags:

views:

47

answers:

3

Hello,

Let's say we have the following XML document:

<root>
    <options>
        ...
    </options>
    <children>
        <child name="first">12345</child>
        <child name="second">
            <additionalInfo>abcd</additionalInfo>
    </children>
</root>

I would like to get a string representation of the "child" nodes and append them into an array (I don't want to lose the XML syntax so .text() is not an option). For example, the first child would look like:

QString child = "<child name="first">12345</child>";

I used the following code to get the elements:

QDomDocument doc;
QDomElement element;
element = xml->documentElement();
if(element.isNull() == false)
{
    element = element.firstChildElement("children");
    if(element.isNull()) return;

    element = element.firstChildElement("child");
    while(element.isNull() == false)
    {
        doc = element.toDocument();
        if(doc.isNull() == false)
        {
            // save string into array
            array.append(doc.toString());
        }
        element = element.nextSiblingElement("child");
    }
}

The problem is that the doc.isNull returns always false (looks like I'm unable to convert the element into document). Is there any way how I can perform this?

Edit:

I would like to add that QString is not mandatory here. Basically any class that can be later used to retrieve the data is ok (I'll save these nodes and use them to initialize another objects later on). Important thing is that I should be able to access those values even when the original document have been destroyed.For example, it it possible to store those elements directly to some array (e.g. QList), which can be used to access them later on.

A: 

Since you need the XML format itself you don't need QDomElement or QDomDocument. QDomElement and QDomDocument are used to obtain the data stored in the XML documents.

You just need a ordinary file traversal.

Open the file using

bool QFile::open ( OpenMode mode )   [virtual]

You can read the entire contents of the file by,

QByteArray QIODevice::readAll ()

which you can assign it to an QString.

For e.g.,

QString entireContents = xmlFile->readAll();

Then you can split the entire contents based on the newline \n character using

QStringList QString::split ( const QString & sep, SplitBehavior behavior = KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive ) const

Now each index corresponds to each line in the XML file. You can traverse through it and obtain the desired lines of interest.

Hope it helps...

liaK
Ty for reply. I'm using those QDom* classes because I also need to parse/obtain a lot data prior to the discussed operation. Thats why I'm curious if those this can be done via those classes (or any QtXml classes).I know it is possible to parse the document "by hand" and it might work with a simple document. However, in my situation the document might be very complex and I need similar operations in multiple places. Basically all I know is that there should be a node on certain level of the XML tree and I need to get every branch under it.
Routa
A: 

Well i think you cant do excactly what you want with the Qt XML classes, but it should be possible to simply reconstruct the string yourself (perhaps not matching the original in 100%, but with the same meaning), based on the methods the Qt XML classes provide.

EDIT: Small code snippet which might do the thing (untested):

QString domElementToRawXML(const QDomElement& elem)
{
    QString head = "<"+elem.tagName();
    QDomNamedNodeMap attrs = elem.attributes();
    for(int i = 0; i<attrs.size(); ++i)
    {
        QDomAttr attr = attrs.item(i).toAttr();
        head += 
            QString::fromLatin1(" %0=\"%1\"")
            .arg(attr.name())
            .arg(attr.value());
    }
    head += ">";
    return head + elem.text() + "</"+elem.tagName()+">";
}
smerlin
Thanks for the reply. Based on these answers it looks like I have to abandon the strategy of saving the nodes (as a string) and figure out something else.
Routa
A: 

I'll add an answer to my own question. No idea why, but looks like I missed the following function in the documentation.

void QDomNode::save ( QTextStream & str, int indent ) const

It does pretty much all I need to convert a node into a string, e.g:

QString str;
QTextStream stream(str);
QDomNode node = xml->documentElement().firstChildElement("child");

node.save(stream, 4);

// process str
Routa