Seite 1 von 1

QDomDocument Strukturparser

Verfasst: 17. Dezember 2012 16:51
von Necropsy
Guten Tag,

Ich habe mit der QT Klasse QDomDocument versucht einen parser für XML zu schreiben allerdings komm ich nicht so ganz vorran. Ich komme einfach nicht über den Punkt hinaus die unterelemente von den Tags <message> zu wechseln.

ein Beispiel:

Code: Alles auswählen

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="en_US" sourcelanguage="en_GB">
<context>
    <name>client</name>
    <message>
        <source>Refresh</source>
        <comment>action name</comment>
        <translation>Refresh</translation>
    </message>
    <message>
        <source>All Measures</source>
        <comment>action name</comment>
        <translation>All Measures</translation>
    </message>
    <message>
        <source>normal</source>
        <translation>normal</translation>
    </message>
   </name>
 </context>
</TS>
Ich bekomme alles bis zum Source-Tag ausgelesen allerdings weiss ich nicht wie ich die anderen Tags auslese ich habe schon versucht mit nextSibling() da rumzuwerkeln aber die Ausgabe die ich mit QDebug<tagName()> erstelle bleibt immer <source>.

und hier nochmal mein Code fals er benötigt wird.

Hier ist mein Aufruf.

Code: Alles auswählen

  
     QFile xmlFile(targetPath);

    xmlFile.open(QIODevice::ReadOnly);

    QByteArray xmlData(xmlFile.readAll());

     myDoc.setContent(xmlData);

    QDomElement root = doc.documentElement();

    QDomNode node = root.firstChild();
    while(!node.isNull())
    {
        if(node.toElement().tagName() == "context")
        {
            parseEntry(node.toElement());
            node = node.nextSibling();
        }
    }

Parseklasse.

Code: Alles auswählen

void MainWindow::parseEntry(const QDomElement &element)
{
    QDomNode node = element.firstChild();
    while(!node.isNull())
    {
        if(node.toElement().tagName() == "name"){
            QDomNode childNode = node.firstChild();
            while(!childNode.isNull())
            {
                if(childNode.nodeType() == QDomNode::TextNode)
                {
                    QDomNode underChild = childNode.firstChild();
                    QString stringChild = underChild.toElement().tagName();
                }
                childNode = childNode.nextSibling();
            }
        }else if(node.toElement().tagName() == "message")
        {
            QDomNode childNode = node.firstChild();
            while(!childNode.isNull())
            {
                if(childNode.nodeType() == QDomNode::TextNode)
                {
                    QDomNode underChild = childNode.firstChild();
                    QString stringChild = underChild.toElement().tagName();
                }
                childNode = childNode.nextSibling();
            }
        }
        node = node.nextSibling();
    }
}
Vielen dank für eure Zeit.
lg Necropsy

Re: QDomDocument Strukturparser

Verfasst: 17. Dezember 2012 17:40
von Christian81
Arbeite mit QDomNode::firstChildElement ( const QString & tagName = QString() ) anstatt über alle Nodes zu iterieren. Dann kommst Du ganz schnell dahin wo du hin willst.

Re: QDomDocument Strukturparser

Verfasst: 17. Dezember 2012 17:51
von Necropsy
Also ich hab es damit ausprobiert aber die Ausgabe ist trotzdem leer bzw es kommt nichts :/
eventuell wäre ne kleine Erklärung oder ein Beispiel hilfreich.

lg Necropsy

Re: QDomDocument Strukturparser

Verfasst: 18. Dezember 2012 10:39
von Necropsy
Okay das funktioniert soweit aber ich weiss nicht wie ich in den nächste <message> tag komme.

Re: QDomDocument Strukturparser

Verfasst: 18. Dezember 2012 11:31
von Christian81
Steht doch in der Beschreibung von firstChildElement() ... nextSiblingElement()

Re: QDomDocument Strukturparser

Verfasst: 18. Dezember 2012 11:34
von Necropsy
wie hab ich das den anzuwenden?
root.firstChild().nextSibling();

oder?

QDomNode child = root.firstChild();
child.nextSibling();

oder?

QDomNode child = root.firstChild();
child = child.nextSibling();

Re: QDomDocument Strukturparser

Verfasst: 19. Dezember 2012 10:39
von Necropsy
Also ich komme in den ersten Message-Tag

Element ist der root den ich aus dem QDomDocument herausziehe.
die Variablen mit actually am Anfang in ihren namen sind am alle 0 zu Beginn.

Code: Alles auswählen

    QDomNode node = element.firstChild();
    QDomNodeList tempNodeList = element.childNodes();
    int nodeCount = tempNodeList.count();

    while(actuallyNodeContext < nodeCount)
    {
        if(node.hasChildNodes())
        {
            QDomNodeList tempNodeChildList = node.childNodes();
            int nodeChildCount = tempNodeChildList.count();

            while(actuallyChildContextNode < nodeChildCount)
            {
                if(actuallyChildContextNode < 1)
                {
                    QDomNode nameChild = node.firstChildElement("name");

                    qDebug()<<nameChild.firstChild().toText().data();

                    nameChild.clear();
                }else{
                    QDomNode messageChild = node.firstChildElement("message");

                    qDebug()<<messageChild.firstChild().toElement().tagName()<<"line: "<<messageChild.firstChild().toElement().attribute("line");

                    messageChild.clear();
                    messageChild = node.firstChildElement("message").nextSibling();
                    qDebug()<<messageChild.toElement().tagName();
                }
                actuallyChildContextNode++;
            }
        }else{
            node = node.nextSibling();
        }
        node = node.nextSibling();
        actuallyChildContextNode = 0;
        actuallyNodeContext++;
    }
}
Der name wird richtig herausgefilter und er bekommt den erste message-tag allerdings, bekomm ich unter den Message tag immer das selbe attribute von "line" (immer von dem ersten Location).

und hier ist der Knackpunkt wo ich es einfach nicht schaffe das nächste Unterelement zb location oder source auszulesen.
ausserdem bekomm ich es auch nicht hin zwischen den message tags zu wechseln.

Code: Alles auswählen

    <message>
        <location filename="pfad_1" line="2142"/>
        <source>Refresh</source>
        <comment>action name</comment>
        <translation>Refresh</translation>
    </message>
    <message>
        <location filename="pfad_2" line="2149"/>
        <source>All Measures</source>
        <comment>action name</comment>
        <translation>All Measures</translation>
    </message>
    <message>
        <location filename="pfad_3" line="2162"/>
        <source>normal</source>
        <translation>normal</translation>
    </message>

Re: QDomDocument Strukturparser

Verfasst: 19. Dezember 2012 11:24
von Christian81
Warum benutzt Du nicht einfach die Funktionen die ich gesagt habe?
Angenommen domRoot ist <context>

Code: Alles auswählen

QDomElement name = domRoot.firstChildElement("name");
QDomElement msg1 = domRoot.firstChildElement("message");
QDomElement msg2 = msg1.nextSiblingElement("message");
...

Re: QDomDocument Strukturparser

Verfasst: 19. Dezember 2012 11:43
von Necropsy
Entschuldigung ich bin etwas verwirrt zeitweilen durch mein eigenes gescripte xD aber danke nochmal für deine Hilfe, ich denke ich bekomm das nun hin.

Re: QDomDocument Strukturparser

Verfasst: 2. Januar 2013 12:26
von Necropsy
Ich habe noch eine Frage.

Wie bekomme ich <?xml version="1.0" encoding="utf-8"?> und <!DOCTYPE TS> als Elemente?

Ich hab echt keine Ahnung und es wäre toll wenn mir jemand ein kurzes Beispiel postet.

Ich erstelle ein QByteArray womit ich das file auslese und dan setze ich das QDomDocument damit.

Code: Alles auswählen

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="en_US" sourcelanguage="en_GB">
<context>
    <name>client</name>
    <message>
        <source>Refresh</source>
        <comment>action name</comment>
        <translation>Refresh</translation>
    </message>
   </name>
 </context>
</TS>
lg Necropsy

Re: QDomDocument Strukturparser

Verfasst: 2. Januar 2013 15:53
von Necropsy
Hatt sich erledigt.

Ich bin nun durch mit dem Thema danke an Christian81 für seine Geduld.

lg Necropsy