Question

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.

Was it helpful?

Solution

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 /*indent*/);

// process str

OTHER TIPS

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...

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()+">";
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top