Seite 1 von 1

XML-Datei einlesen

Verfasst: 8. Januar 2008 09:29
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

Verfasst: 8. Januar 2008 19:28
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.

Komme nicht weiter

Verfasst: 10. Januar 2008 13:35
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

Verfasst: 10. Januar 2008 17:24
von upsala
Könnte mir jemand helfen die Ausgabe zu formatiere.
Nein, warum? Was gefällt dir an meiner Antwort nicht?

Hast ja Recht!

Verfasst: 11. Januar 2008 09:14
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.