QDom (XML)

Alles rund um die Programmierung mit Qt
Antworten
ChMaster
Beiträge: 252
Registriert: 23. Februar 2005 14:44
Wohnort: RP -> Alzey
Kontaktdaten:

QDom (XML)

Beitrag von ChMaster »

moin habe da ein kleines problemchen :)

das ist mein xmlparser für bestimmte dateien

Code: Alles auswählen

void MasterLevel_XmlParser::readDataGroup( QFile &filename, QListBox *lbx )
{
	QListBox *lbi = new QListBox( lbx );
	QFile *file = new QFile( filename );

    if (!file->open(IO_ReadOnly)) return; // kann datei nicht lesen
    
	QDomDocument doc;
    if (!doc.setContent(file)) return; // kann datei nicht parsen
    
	QDomElement rootElement = doc.documentElement();
    QDomNodeList groupName = rootElement.childNodes();
    for (uint i = 0; i < groupName.length(); ++i)
	{
		QDomNode node = groupName.item(i);
        if (node.isNull() || !node.isElement() || node.nodeName() != "group") continue;
        
		QDomElement element = node.toElement();
        QString name = element.attribute("name");
		lbi->insertItem( name );
		
	}
}
wenn ich aber jetzt in der ListBox ein Item anklick passiert rein nix
(das SIGNAL steht beim anklicken auf highlighted(int), im Qt Designer
erstelltes form). der aufruf: (abgeleitete klasse vom uifile)

Code: Alles auswählen

void QDAoCGR_MasterLevel::slotAuswahl_Reich()
{
	QString alb, hib, mid;
	alb.append( "masterlevel/albion.xml" );
	hib.append( "masterlevel/hibernia.xml" );
	mid.append( "masterlevel/midgard.xml" );

	QFile alb_file( alb );
	QFile hib_file( hib );
   QFile mid_file( mid );

	MasterLevel_XmlParser ml_parser;

	/*
	 * Auswahl der einzelnen Reiche
    * Übergebe das QFile und die QListBox an den parser
    * wenn erfolge, zeige die einzelnen Namen in der 2
    * QListbox: listBox_Klasse an.
	 */
	if ( listBox_Reich->isSelected(1) ){
		ml_parser.readDataGroup( alb_file, listBox_Klasse );
	}else if( listBox_Reich->item(2) ){
		ml_parser.readDataOption( hib_file, listBox_Klasse );
	}else if( listBox_Reich->item(3) ){
		ml_parser.readDataGroup( hib_file, listBox_Klasse );
	}else{
		QMessageBox::information( this, "DAoC - GR", "Kann die angegebene Datei nicht finden." );
	}
}
mein problem ist:
Ich klick auf die 1 ListBox (1 Item, usw.) danach soll er die datei auslesen
und die namen in der 2 ListBox anzeigen, was läuft da falsch? bzw. was mah ich da falsch?

auschnitt aus der xmldatei: (was in group name steht soll er in der 2
QListBox anzeiegen, anschliessen drück ich den namen an soll er dann in
er 3 QListBox den option key anzeigen)

Code: Alles auswählen

<Albion_ML application="DAoC-GR" version="v1" >
<group name="Waffenmeister" >
<option key="Kampfmeister" />
<option key="Kriegsherr" />
</group>
<group name="Kabbalist" >
<option key="Anrufer" />
<option key="Sturmlord" />
</group>
<group name="Kleriker" >
<option key="Kriegsherr" />
<option key="Vollender" />
</group>
<group name="Ordensbruder" >
<option key="Kampfmeister" />
<option key="Vollender" />
</group>
<group name="Infiltrator" >
<option key="Meisterspion" />
<option key="Kampfmeister" />
</group>
......
ChMaster
------------ Projekte------------
DBoxFE
DMS
First4 (Plugin-Develper)
Notwist
Beiträge: 85
Registriert: 2. März 2005 14:24

Beitrag von Notwist »

Guck doch erstmal mit dem Debugger, ob er auf das Signal überhaupt reagiert & reinspringt. Dann kannst Du schon mal eingrenzen, wie weit das Ganze schon läuft.
Gruß, Notwist
Goos
Beiträge: 360
Registriert: 17. August 2004 10:10
Wohnort: Black Forest

Re: QDom (XML)

Beitrag von Goos »

ChMaster hat geschrieben:moin habe da ein kleines problemchen :)

das ist mein xmlparser für bestimmte dateien

Code: Alles auswählen

void MasterLevel_XmlParser::readDataGroup( QFile &filename, QListBox *lbx )
{
	QListBox *lbi = new QListBox( lbx );
	QFile *file = new QFile( filename );

    if (!file->open(IO_ReadOnly)) return; // kann datei nicht lesen
    
	QDomDocument doc;
    if (!doc.setContent(file)) return; // kann datei nicht parsen
    
	QDomElement rootElement = doc.documentElement();
    QDomNodeList groupName = rootElement.childNodes();
    for (uint i = 0; i < groupName.length(); ++i)
	{
		QDomNode node = groupName.item(i);
        if (node.isNull() || !node.isElement() || node.nodeName() != "group") continue;
        
		QDomElement element = node.toElement();
        QString name = element.attribute("name");
		lbi->insertItem( name );
		
	}
}
QFile *file = new QFile( filename ); <-- Dem QFile Konstuktor kannst vielleicht einen QString uebergeben, aber sicher keine QFile Referenz. Du fliegst also sicher aus deiner readDataGroup Methode schon beil file->open() raus :)
Aehnlich schlimm schauts bei deiner QListbox aus. Zudem erzeugst da auch noch ne neue QListbox lokal in deiner readDataGroup Methode.
Dieser wird also schon wieder zerstoert, wenn du readDataGroup verlaesst und du hast sie da noch nichtmal deleted (schaem dich ;) ).
Du solltest ausserdem bei readDataGroup wenigstens nen bool zurueckgeben um zu merken, ob es geklappt hat oder nicht (was aber auch nicht wirklich optimal ist, da du mehrere Ausstiegspunkte hast) ;)

Goos
ChMaster
Beiträge: 252
Registriert: 23. Februar 2005 14:44
Wohnort: RP -> Alzey
Kontaktdaten:

Beitrag von ChMaster »

danke für eure mühen, habe da was anderes und hier das, was funktioniert:
(QListView benutzt, ist einfacher) ;)

CPP

Code: Alles auswählen

#include "../header/ml_xmlparser.h"

#include <qdom.h>
#include <qlistview.h>
#include <qiodevice.h>

MLXmlParser::MLXmlParser( QIODevice *device, QListView *view )
{
     listView = view;
     
     QString errorStr;
     int errorLine;
     int errorColumn;
     
     QDomDocument doc;
     if( !doc.setContent( device, true, &errorStr, &errorLine, &errorColumn ) ){
         qWarning("Zeile: %d, Spalte %d:", errorLine, errorColumn, errorStr.ascii() );
     }
     
     QDomElement root = doc.documentElement();
     if( root.tagName() != "masterlevel_klassen" ){
         qWarning( "Dies ist nicht die richtige XML datei" );
     }
     
     QDomNode node = root.firstChild();
     while( !node.isNull() ){
            if( node.toElement().tagName() == "group" )
                parseEntry( node.toElement(), 0 );
            node = node.nextSibling();
     }            
}

void MLXmlParser::parseEntry( const QDomElement &element, QListViewItem *parent )
{
     QListViewItem *item;
     if( parent ){
         item = new QListViewItem( parent );
     } else {
         item = new QListViewItem(  listView );
     }
     item->setOpen( true );
     item->setText( 0, element.attribute( "name" ) );
     
     QDomNode node = element.firstChild();
     while( !node.isNull() ){
            if( node.toElement().tagName() == "group" ){
                parseEntry( node.toElement(), item );
            } else if( node.toElement().tagName() == "page" ){
                   QDomNode childNode = node.firstChild();
                   while( !childNode.isNull() ){
                          if( childNode.nodeType() == QDomNode::TextNode ){
                              QString page = childNode.toText().data();
                              QString allPage = item->text(1);
                              if( !allPage.isEmpty() )
                                  allPage += ", ";
                              allPage += page;
                              item->setText( 1, allPage );
                              break;
                          }
                          childNode = childNode.nextSibling();
                   }
            }
            node = node.nextSibling();            
     }     
}
HEADER

Code: Alles auswählen

class QIODevice;
class QDomElement;
class QListView;
class QListViewItem;

class MLXmlParser
{
      public:
          MLXmlParser( QIODevice *device, QListView *view );
             
      private:
          void parseEntry( const QDomElement &element, QListViewItem *parent );
          
          QListView *listView;    
};
aufruf:

Code: Alles auswählen

    QString all;
    all.append( "masterlevel/all.xml" );
   	QFile file( all );
   	//slotListView();
	MLXmlParser( &file, lv_All);
aufbau der XML datei :)

Code: Alles auswählen

<?xml version="1.0"?>
<masterlevel_klassen>
	<group name="Albion">
		<group name="Waffenmeister">
			<group name="Kampfmeister">
				<page></page>
			</group>
			<group name="Kriegsherr">
				<page></page>
			</group>
		</group>		
...........
habe das bsp in einem Qt Buch gefunden und etwas umgemodelt ;)
somit funktioniert es.
ChMaster
------------ Projekte------------
DBoxFE
DMS
First4 (Plugin-Develper)
Antworten