2010-07-14 7 views
8

Lassen Sie uns sagen, dass wir das folgende XML-Dokument haben:Converting QDomElement zu QString/Container-Klasse

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

Ich möchte eine String-Repräsentation der „Kind“ Knoten erhalten und sie in ein Array anhängen (I don‘ Ich möchte die XML-Syntax verlieren, also ist .text() keine Option). Zum Beispiel würde das erste Kind wie folgt aussehen:

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

ich den folgenden Code verwendet, um die Elemente zu erhalten:

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"); 
    } 
} 

Das Problem ist, dass die doc.isNull immer false zurück (sieht aus wie ich Ich kann das Element nicht in Dokument konvertieren). Gibt es eine Möglichkeit, wie ich das ausführen kann?

Edit:

Ich mag würde, dass QString hinzuzufügen, ist hier nicht zwingend notwendig. Grundsätzlich ist jede Klasse, die später zum Abrufen der Daten verwendet werden kann, in Ordnung (ich speichere diese Knoten und benutze sie später, um weitere Objekte zu initialisieren). Wichtig ist, dass ich auf diese Werte auch dann zugreifen kann, wenn das Originaldokument zerstört wurde. Beispielsweise ist es möglich, diese Elemente direkt in einem Array zu speichern (z. B. QList), auf die später zugegriffen werden kann.

Antwort

12

Ich werde eine Antwort auf meine eigene Frage hinzufügen. Keine Ahnung warum, aber sieht so aus als hätte ich die folgende Funktion in der Dokumentation verpasst.

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

Es tut so ziemlich alles, was ich einen Knoten in einen String umgewandelt werden müssen, z:

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

node.save(stream, QDomNode::CDATASectionNode /* = 4 *); 

// process str 
+1

Was ist mit der entgegengesetzten Operation? Gegeben die Zeichenfolge generieren einen QDomNode, der später an ein vorhandenes QDomDocument angefügt werden kann? – Pierluigi

+0

@Pierluigi, das sollte eine Frage für sich sein. Es ist ziemlich involviert. Sie erstellen ein 'QDomDocument', verwenden' setContent() 'und verwenden dann' QDomDocumentFragment', um das Ergebnis in ein anderes Dokument zu kopieren ... –

+0

Kommentar/* = 4 * ist nicht geschlossen. Also hier Syntaxis Fehler. –

0

Da Sie das XML-Format selbst benötigen, benötigen Sie nicht QDomElement oder QDomDocument. QDomElement und QDomDocument werden verwendet, um die gespeicherten Daten in den XML-Dokumenten zu erhalten.

Sie brauchen nur eine normale Datei Traversal.

Öffnen Sie die Datei mit

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

Sie den gesamten Inhalt der Datei lesen kann,

QByteArray QIODevice::readAll() 

, die Sie es zu einem QString zuweisen können.

Zum Beispiel

QString entireContents = xmlFile->readAll(); 

Dann können Sie den gesamten Inhalt auf dem

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

nun jeder Index in der XML-Datei, die jeder Zeile entspricht mit Newline\n Charakter basiert aufgeteilt. Sie können hindurchgehen und die gewünschten Linien von Interesse erhalten.

Hoffe, es hilft ...

+0

Ty für die Antwort. Ich benutze diese QDom * -Klassen, weil ich vor der besprochenen Operation auch viele Daten analysieren/erhalten muss. Deshalb bin ich neugierig, ob das über diese Klassen (oder QtXml-Klassen) möglich ist. Ich weiß, es ist möglich, das Dokument "von Hand" zu analysieren und es könnte mit einem einfachen Dokument arbeiten. In meiner Situation ist das Dokument jedoch möglicherweise sehr komplex und ich benötige ähnliche Operationen an mehreren Stellen. Im Grunde ist alles, was ich weiß, dass es auf einer bestimmten Ebene des XML-Baums einen Knoten geben sollte, und ich muss jeden Zweig darunter bekommen. – Routa

0

Nun, ich denke, man kann excactly tun, was Sie mit den XML-Klassen von Qt wollen, aber es sollte möglich sein, einfach die Zeichenfolge zu rekonstruieren selbst (vielleicht nicht das Original in 100 passend %, aber mit derselben Bedeutung), basierend auf den Methoden, die die Qt-XML-Klassen bereitstellen.

EDIT: kleiner Code-Schnipsel, die die Sache (ungetestet) tun könnten:

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()+">"; 
} 
+0

Danke für die Antwort. Aufgrund dieser Antworten scheint es, als müsste ich die Strategie aufgeben, die Knoten (als String) zu speichern und etwas anderes herauszufinden. – Routa