2010-07-14 20 views
8

Supongamos que tenemos el siguiente documento XML:conversión de QDomElement a la clase QString/contenedor

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

me gustaría obtener una representación de cadena de los nodos "niño" y los añade en una matriz (I don' Quiero perder la sintaxis XML para que .text() no sea una opción. Por ejemplo, el primer hijo se vería así:

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

He utilizado el siguiente código para obtener los elementos:

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

El problema es que el doc.isNull siempre devuelve falso (se parece a I' m no puede convertir el elemento en documento). ¿Hay alguna manera de cómo puedo realizar esto?

Editar:

me gustaría añadir que no es obligatorio QString aquí. Básicamente, cualquier clase que pueda usarse posteriormente para recuperar los datos está bien (guardaré estos nodos y los usaré para inicializar otros objetos más adelante). Lo importante es que debería poder acceder a esos valores incluso cuando el documento original haya sido destruido. Por ejemplo, es posible almacenar esos elementos directamente en una matriz (por ejemplo, QList), que se puede usar para acceder a ellos más adelante.

Respuesta

12

Voy a añadir una respuesta a mi propia pregunta. No tengo idea de por qué, pero parece que me perdí la siguiente función en la documentación.

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

Lo hace casi todo lo que necesito para convertir un nodo en una cadena, por ejemplo:

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

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

// process str 
+1

¿Qué pasa con la operación opuesta? Dada la cadena, ¿se genera un QDomNode que luego se puede agregar a un QDomDocument existente? – Pierluigi

+0

@Pierluigi, eso debería ser una pregunta en sí misma. Es bastante complicado. Crea un 'QDomDocument', usa' setContent() ', luego usa' QDomDocumentFragment' para copiar el resultado en otro documento ... –

+0

Comment/* = 4 * no está cerrado. Entonces aquí el error de sintaxis. –

0

Dado que necesita el formato XML en sí no necesita QDomElement o QDomDocument. QDomElement y QDomDocument se usan para obtener los datos almacenados en los documentos XML.

Solo necesita un recorrido normal de archivos.

Abrir el archivo con

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

Usted puede leer todo el contenido del expediente,

QByteArray QIODevice::readAll() 

que se puede asignar a un QString.

Por ejemplo,

QString entireContents = xmlFile->readAll(); 

A continuación, puede dividir el contenido completo basado en el carácter nueva línea\n usando

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

Ahora cada índice corresponde a cada línea en el archivo XML. Puede atravesarlo y obtener las líneas de interés deseadas.

creo que sirve ...

+0

Ty para la respuesta. Estoy usando esas clases QDom * porque también necesito analizar/obtener muchos datos antes de la operación discutida. Es por eso que tengo curiosidad si esto se puede hacer a través de esas clases (o cualquier clase QtXml). Sé que es posible analizar el documento "a mano" y podría funcionar con un documento simple. Sin embargo, en mi situación, el documento puede ser muy complejo y necesito operaciones similares en varios lugares. Básicamente, todo lo que sé es que debería haber un nodo en cierto nivel del árbol XML y necesito tener cada rama debajo de él. – Routa

0

Bueno, yo creo que no puede hacer realidad sea exactamente lo que quiere con las clases XML Qt, pero debería ser posible simplemente reconstruir la cadena de sí mismo (tal vez no coincida con el original en 100 %, pero con el mismo significado), en función de los métodos que proporcionan las clases XML de Qt.

EDIT: pequeño fragmento de código que podría hacer la cosa (no probado):

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

Gracias por la respuesta. En función de estas respuestas, parece que tengo que abandonar la estrategia de guardar los nodos (como una cadena) y descubrir algo más. – Routa