XML-Datei einlesen

Alles rund um die Programmierung mit Qt
Antworten
wafelek
Beiträge: 12
Registriert: 18. Oktober 2007 12:05

XML-Datei einlesen

Beitrag von wafelek »

Hallo zusammen!

Habe folgendes Problem, ich möchte mit Hilfe des Parsers SAX die folgende XML-Datei
<?xml version="1.0" encoding="UTF-8"?>
<DataBase Name="Measdata">
<Table Name="BoardData">
<Table Name="BatchInfo">
<Batch>MANUAL_19_07_2007</Batch>
<Table Name="LayerData">
<tm>2007-07-19 16:48:03</tm>
<si>0</si>
<mm>1</mm>
<em>1</em>
<dm>2</dm>
<te>2</te>
<Table Name="ProductInfo">
<Product>oir600_m7_201206_1.EX2</Product>
</Table>
</Table>
</Table>
</Table>
</DataBase>
als ein Insert-SQL-Befehl wie folgt ausgeben lassen:
INSERT INTO BatchInfo (Batch) VALUES ('MANUAL_19_07_2007')
INSERT INTO LayerData (tm, si, mm, em, dm, te) VALUES ('2007-07-19 16:48:03', 0, 1, 1, 2, 2)
INSERT INTO ProductInfo (Product) VALUES ('oir600_m7_201206_1.EX2')
So sieht zur Zeit mein Quellcode aus:

Code: Alles auswählen

bool XMLParser::startDocument ()		
	{
	return true;
	}

bool XMLParser::startElement ( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& attributes)	
	{

	if	(m_Level+1 <= MAX_LEVEL)
		{
		m_Level += 1;
		m_Characters[m_Level] = "";
		}
	else
		{
		//Abbruch Fehler
		}


	if	((qName != "DataBase") && (qName != "Table"))
		{
		m_isCharacter = 1;
		m_DatafieldName[m_Level] = qName;

		}


	if	(attributes.length() > 0 ) 
		{	
		for (int a=0; a < attributes.count(); a++)
			{
			
			if	(qName == "DataBase")
				{
				m_isDatabase = 1;
				m_isCharacter = 0;
				m_DataSourceName[m_Level] = attributes.value(a).stripWhiteSpace() + "@user/pass";
				m_OutputView->setText( m_OutputView->text() + "DatabaseName: " + m_DataSourceName[m_Level] + "\n");
				} else
			if	(qName == "Table")
				{
				m_isCharacter = 0;
				m_TableName[m_Level] = attributes.value(a).stripWhiteSpace();
				m_OutputView->setText( m_OutputView->text() + "TableName: " + m_TableName[m_Level] + "\n");
				} 
			}	
		}
	return true;   
	} 

 bool XMLParser::endElement ( const QString&, const QString&, const QString& qName)	
	{
	m_SQL_Statement += m_TableName[m_Level];
	m_SQL_Statement += m_DatafieldList[m_Level];
	m_SQL_Statement += m_ValueList[m_Level];
	m_DatafieldList[m_Level] += m_DatafieldName[m_Level] + ", ";
	m_Level -=1;

	if	(!m_ValueList[m_Level].isEmpty())
		{
		m_ValueList[m_Level] += 1;
		}
	m_ValueList[m_Level] += m_Characters[m_Level];
	return true;
	}

//Hier wird der SQL-Befehl über die Array ausgegeben...............

bool XMLParser::characters ( const QString & ch ) 
	{

	if	((m_isCharacter == 1) && (!m_DatafieldName[m_Level].isEmpty()))
		{
		m_Characters[m_Level] += ch;

		m_ValueList[m_Level] = ch.stripWhiteSpace();
		m_OutputView->setText(m_OutputView->text() + "INSERT INTO"+ " " + m_TableName[m_Level-1] + " " + "(" + m_DatafieldList[m_Level]  + ")" + " VALUES ('" + m_ValueList[m_Level] + "')" + "\n");
		}
	return true;
	}

und so sieht die aktuelle Ausgabe aus:
DatabaseName: Measdata@user/pass
TableName: BoardData
TableName: BatchInfo
INSERT INTO BatchInfo () VALUES ('MANUAL_19_07_2007')
TableName: LayerData
INSERT INTO LayerData () VALUES ('2007-07-19 16:48:03')
INSERT INTO BatchInfo (Batch, ) VALUES ('')
INSERT INTO LayerData (tm, ) VALUES ('0')
INSERT INTO BatchInfo (Batch, ) VALUES ('')
INSERT INTO LayerData (tm, si, ) VALUES ('1')
INSERT INTO BatchInfo (Batch, ) VALUES ('')
INSERT INTO LayerData (tm, si, mm, ) VALUES ('1')
INSERT INTO BatchInfo (Batch, ) VALUES ('')
INSERT INTO LayerData (tm, si, mm, em, ) VALUES ('2')
INSERT INTO BatchInfo (Batch, ) VALUES ('')
INSERT INTO LayerData (tm, si, mm, em, dm, ) VALUES ('2')
INSERT INTO BatchInfo (Batch, ) VALUES ('')
INSERT INTO LayerData (tm, si, mm, em, dm, te, ) VALUES ('0000.2')
TableName: ProductInfo
INSERT INTO ProductInfo () VALUES ('oir600_m7_201206_1.EX2')
Könnte mir jemand helfen meine Ausgabe zu formatieren, so daß ich meine SQL-Befehle bekomme.

MfG
Daniel
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Warum führst du dieses Topic nicht weiter?

Ich würde bei startElement die Daten in einem Stack zwischenspeichern (QStack). Die Attribute kannst du ja in einer QMap oder einem QHash ablegen.
Bei endElement hast du dann alle Daten beisammen und kannst mit den QString-Funktionen einen passenden String zusammensetzen.
wafelek
Beiträge: 12
Registriert: 18. Oktober 2007 12:05

Komme nicht weiter

Beitrag von wafelek »

Also ich bekomme mitleiweile folgende Ausgabe:
INSERT INTO BatchInfo () VALUES ('MANUAL_19_07_2007')
INSERT INTO BoardData () VALUES ('2007-07-19 16:48:03')
INSERT INTO BatchInfo (Batch, ) VALUES ('')
INSERT INTO BoardData (tm, ) VALUES ('0')
Möchte die Ausgabe aber so haben:
INSERT INTO BatchInfo (Batch) VALUES ('MANUAL_19_07_2007')
INSERT INTO BoardData (tm, si) VALUES ('2007-07-19 16:48:03', '0')
Hier kommt mein Quelltext:

Code: Alles auswählen

bool XMLParser::startElement ( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& attributes)	
	{
	if	(m_Level+1 <= MAX_LEVEL)
		{
		m_Level += 1;
		m_Characters[m_Level] = "";
		}
	else
		{
		return false;
		}

//	output: DatafieldName
	if	((qName != "DataBase") && (qName != "Table"))
		{
		m_isCharacter = 1;
	        m_DatafieldName[m_Level] = qName.stripWhiteSpace();
		}
	if	(attributes.length() > 0 ) 
		{	
		for (int a=0; a < attributes.count(); a++)
			{
			if	(qName == "DataBase")
				{
				m_isCharacter = 0;
				m_DataSourceName[m_Level] = attributes.value(a).stripWhiteSpace() + "@user/pass";
				} else
			if	(qName == "Table")
				{
				m_isCharacter = 0;
				m_TableName[m_Level] = attributes.value(a).stripWhiteSpace();
				} 
			}	
		}
	return true;   
	} 

bool XMLParser::endElement ( const QString&, const QString&, const QString& qName)	
	{
	m_SQL_Statement += m_TableName[m_Level-1];
	m_SQL_Statement += m_DatafieldList[m_Level];
	m_SQL_Statement += m_ValueList[m_Level];
	m_DatafieldList[m_Level] += m_DatafieldName[m_Level] + ", ";
	m_Level -=1;
	if	(!m_ValueList[m_Level].isEmpty())
		{
		m_ValueList[m_Level] += 1;
		}
	m_ValueList[m_Level] += m_Characters[m_Level];
	m_OutputView->setText( m_OutputView->text() + "endElement: " + qName + "\n" );
	return true;
	}

bool XMLParser::characters ( const QString & ch ) 
	{
  if	((m_isCharacter == 1) && (!m_DatafieldName[m_Level].isEmpty()))
		{
		m_Characters[m_Level] += ch;
		m_ValueList[m_Level] = ch.stripWhiteSpace();
		m_OutputView->setText(m_OutputView->text() + "INSERT INTO"+ " " + m_TableName[m_Level-1] + " " + "(" + m_DatafieldList[m_Level]  + ")" + " VALUES ('" + m_ValueList[m_Level] + "')" + "\n");
		}
	return true;
	} 
Könnte mir jemand helfen die Ausgabe zu formatiere.

MfG
Daniel
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Könnte mir jemand helfen die Ausgabe zu formatiere.
Nein, warum? Was gefällt dir an meiner Antwort nicht?
wafelek
Beiträge: 12
Registriert: 18. Oktober 2007 12:05

Hast ja Recht!

Beitrag von wafelek »

Die Antwort ist ja prima, ich habe doch ein Array den über Level indiziere, das funktioniert doch genau so, oder sollte ich es ganz weg lassen und neu über Stack machen. Da ich ein Anfänger bin tue ich mir etwas schwer mit Pointern zu arbeiten.

Also ich habe das folgende Bsp gefunden:

Code: Alles auswählen

if ( ! stack.isEmpty() ){
	QListViewItem *lastChild = stack.top()->firstChild();
	if ( lastChild ) {
	    while ( lastChild->nextSibling() )
		lastChild = lastChild->nextSibling();
	}
	element = new QListViewItem( stack.top(), lastChild, qName, namespaceURI );
    } else {
	element = new QListViewItem( table, qName, namespaceURI );
    }
    stack.push( element );
    element->setOpen( TRUE );

    if ( attributes.length() > 0 ) {
	for ( int i = 0 ; i < attributes.length(); i++ ) {
	    new QListViewItem( element, attributes.qName(i), attributes.uri(i) );
	}
    }
    return TRUE;
} 
Ich habe aber keine QListView, sondern QTextBrowser.
Dieser kennt aber kein lastChild nextSibling()
WIe müsste der QPtrStack aussehen wenn ich nur die Tabellename aus meinem XML haben möchte.
Antworten