Xml auslesen



  • Hallo,
    ich habe da ein Problem und hoffe hier jemanden zu finden, der mehr Ahnung hat als ich.
    Also, ich möchte eine XML-Datei auslesen.
    Die Datei is so aufgebaut:
    <a>
    <b>
    <c>
    <d attribut="1">
    etc.
    Ich möchte nur wissen, ob das Attribut 1 oder 0 ist.
    Habe probiert mit Foren oder Google weiter zu kommen, aber bis jetzt.... naja.
    Ich arbeite mit Visual Studio 2005 und benutze msxml6 zum parsen.

    Bisher schaffe ich es die Datei zu laden:

    // Initialisierung DOM
    	::CoInitialize(NULL);
    
    	HRESULT hr = m_plDocument.CreateInstance(CLSID_DOMDocument);
    	if(FAILED(hr))
    	{
    		_com_error er(hr);
    		AfxMessageBox(er.ErrorMessage());
    		EndDialog(1);
    
    	}
    	//XML-Datei Name
    	CString strFileName ("C:\\Dokumente und Einstellungen\\test.xml");
    
    	//CString in BSTR
    	_bstr_t bstrFileName;
    	bstrFileName = strFileName.AllocSysString();
    
    	//Laden des Dokuments
    	variant_t vResult;
    	vResult = m_plDocument->load(bstrFileName);
    	if (((bool)vResult) == TRUE)
    	{
    		m_pDocRoot = m_plDocument->documentElement;
    		AfxMessageBox("Erfolgreich geladen");
    	}
    	else
    	{
    		AfxMessageBox("Laden fehlgeschlagen");
    	}
    	AfxMessageBox(m_plDocument->xml);
    

    Und einmal "durchzulaufen":

    void CXMLTestDlg::OnBnClickedOk()
    {
    	DisplayChildren(m_pDocRoot);
    	OnOK();
    }
    
    void CXMLTestDlg::DisplayChildren(MSXML2::IXMLDOMNodePtr pParent)
    {
    	DisplayChild(pParent);
    
    	for (MSXML2::IXMLDOMNodePtr  pChild= pParent->firstChild;
    		NULL != pChild;
    		pChild = pChild->nextSibling)
    	{
    			DisplayChildren(pChild);
    	}	
    }
    
    void CXMLTestDlg::DisplayChild(MSXML2::IXMLDOMNodePtr pChild)
    {
    	if (MSXML2::NODE_TEXT == pChild->nodeType)
    	{
    		AfxMessageBox(pChild->text);
    	}
    	else
    	{
    		AfxMessageBox(pChild->nodeName);
    	}
    }
    

    Aber ich weiß einfach nicht, wie ich das Attribut überprüfen kann. 😕
    Vielleicht hat ja jemand Erfahrung damit und kann mir helfen.

    Gruß Janinoe



  • Kenne mich zwar mit Visual Studio nicht aus, aber wenn es ähnlich wie PHP ist, dann hast du zwei Möglichkeiten.

    1.Möglichkeit:
    - Datei einlesen
    - einen möglichst eindeutigen Satz raussuchen, der vor den Daten liegt
    - Ab dieser STRING Position alles bis zum Ende in eine Variable lesen
    - zweiten Datenteil (Ende deines Datensatzes bestimmen) den Rest mit Leerzeichen auffüllen.
    - übriggebliebener Teil in deine Variable schieben und dann mit StringPos Funktionen so auftrennen wie deine Daten kommen. Und mit Split die Daten raustrennen

    bsp aufsplitten in PHP Dateien:
    fgetss liest mehrere Zeilen ein und hebt die HTML formatierung hervor.

    while($zeile = fgetss($fp,3554431,"<a><b><c><d attribut="1">"))
     {
      $i = strlen($zeile);
      $resa=$zeile;
     }
    
    // Daten rausfiltern
    
    if($resb = strstr($resa,$startstring ))  // hier wird der startstring in $resa gesucht und ab da in resb eingetragen
    if($resa = strstr($resb,$endstring ))    // hier wird der endstring in $resb gesucht und ab da in resa eingetragen
    $resultat = str_replace($resa,"",$resb); // hier wird resa in resb durch Leerzeichen ersetzt
    

    Viel eleganter geht es mit Regex in dem du dir mit Platzhaltern genau den Teil vom Code rausholst, den du haben möchtest, ohne den ganzen Mist mit Positionen rausschneiden. Hat den Vorteil, dass sich eine Datei auch von der Länge her ändern kann und die Ausdrücke trotzdem gefunden werden wenn sie dem Suchmuster entsprechen.

    bsp mit Regex nach einem Datum suchen

    //-- Prüfen ob Datum, Uhrzeit vorhanden, anschließend Ausgabe
    
    				//-- Suchmuster festlegen
    
    					$suchmuster_Datum = '/(\d+).(\d+). \/ (\d+)\:(\d+)Uhr/';
    
    				//-- Ausgabe Datum / Uhrzeit
    
    					if(preg_match($suchmuster_Datum,$inhalt,$Datum_split))
    

    Zieh dir mal den Link rein, kann dir da sicher weiterhelfen

    http://www.regenechsen.de/phpwcms/index.php?regex_dt_tb

    Grüße
    egcactus



  • 1.

    Visual Studio 2005

    Ist zwar nicht dringend notwendig, aber ne neure Version wär zumindest kein Nachteil ^^
    2.

    Visual Studio [...] ähnlich wie PHP

    O.O Wie kann man ne IDE mit ner Skriptsprache vergleichen? Oo

    Zum eigentlichen Thema:
    Guck dir mal std::ifstream und std::ofstream an (entweder hier im Forum danach suchen oder direkt in der MSDN).

    Ansonsten:

    <a> 
    <b> 
    <c> 
    <d attribut="1">
    

    du machst 4 mal

    std::getline (/*dein stream zur datei*/, /*die ausgabe variable - irgend nen std::string eben*/);
    //NACH dem vierten mal: (weil dich ja nur die vierte Zeile interessiert)
    //deine ausgabevariable ist hier jz einfach mal so deklariert "std::string zeile":
    //und dann machst du so was in der art: (die fkt werden alle bissl anders heißen, aber die weiß ich jz nicht ausm kopf, sry...)
    zeile.substring (zeile.findfirst ('='), zeile.length ());
    

    Alternativ könntest du das auch gleich im Stream machen:

    //beim vierten mal so:
    std::string muell;
    std::getline (/*dein stream zur datei*/, muell, '='); //bis zum = auslesen
    std::seekg (1); //eins weiter damit du das '=' überspringst...
    int die_zahl_komma_die_du_suchst (0);
    /*dein stream zur datei*/ >> die_zahl_komma_die_du_suchst;
    

    Weiß nicht, was besser ist und was dir besser gefällt, logischer ist oder wie auch immer

    Vll hats dir ja ein wenig geholfen...

    Bye



  • Hi, danke schon mal für die Antwort.
    Habs zuerst mit Streams versucht, da wurde mir von allen Seiten gesagt, ich soll nen Parser benutzen ^^
    Vielleicht kann mir da ja noch jemand nen Tipp geben...
    Wenn da keiner weiter weiß kann ichs ja noch mal mit Streams versuchen...
    Würd mich aber trotzdem über Antworten freuen 😃

    Gruß



  • <d attribut="1">
    etc.
    Ich möchte nur wissen, ob das Attribut 1 oder 0 ist.

    für so was einfaches würde ich keinen parser nehmen sondern schon streams... (ich würde es allgemein nur mit streams machen - aber das muss ja noch lang ne heißen, dass du es auch so machen musst ^^ und der parser wird dir bestimmt ne menge arbeit abnehmen, wenn du iwann mehr auslesen willst)

    Bye



  • Janinoe schrieb:

    Habs zuerst mit Streams versucht, da wurde mir von allen Seiten gesagt, ich soll nen Parser benutzen ^^
    Vielleicht kann mir da ja noch jemand nen Tipp geben...

    Vielleicht mal im richtigen Unterforum versuchen? MSXML hört sich für mich jedenfalls nicht wie ANSI C++ an, und auch dein Code ist kein ANSI C++. Blind ins Blaue geraten: MFC.

    cu André



  • Janinoe schrieb:

    Hi, danke schon mal für die Antwort.
    Habs zuerst mit Streams versucht, da wurde mir von allen Seiten gesagt, ich soll nen Parser benutzen ^^
    Vielleicht kann mir da ja noch jemand nen Tipp geben...
    Wenn da keiner weiter weiß kann ichs ja noch mal mit Streams versuchen...
    Würd mich aber trotzdem über Antworten freuen 😃

    Gruß

    Mit Streams wirst du auf Dauer nicht glücklich werden.
    Die XML Dateien können ja z.B. beliebig mit Whitespaces "Formatiert" werden.

    Willst du es richtig machen (und dir einiges an Ärger sparen) nimm einen XML-Parser.

    Zum Auslesen der Attribute: eine Node hat eine Eigenschaft "attributes":
    http://msdn2.microsoft.com/en-us/library/ms761386(VS.85).aspx



  • Die XML Dateien können ja z.B. beliebig mit Whitespaces "Formatiert" werden.

    findfirstnot (' '); //oder iwie so ähnlich ^^
    

    aber wie schon gesagt - so bald du mehr als nur die eine zeile brauchst hast du mit dem xml-parser wahrscheinlich 20 zeilen mehr code und mit streams leicht das zehnfache...

    Bye



  • Whitespaces sind auch Zeilenumbrüche und Tabs.
    Z.B.:

    <EinTag
    
      AttributNr1              =
    
    '23' />
    

    Natürlich kann man das auch selber parsen.
    Auf den ersten Blick sieht es einfach aus und man denkt sich, es geht schneller als mit irgendeiner Lib rumzuhantieren.

    Es ist aber in jedem Fall schneller und bequemer mit einem XML-Parser, glaub mir.



  • Nur leider für mich als "Frischling" nicht so einfach 😉



  • Janinoe schrieb:

    Nur leider für mich als "Frischling" nicht so einfach 😉

    Hast du dir meinen Link angesehen?
    Sieht nicht besonders schwer aus die Attribute einer Node auszulesen.



  • Ja, gucke ich mir gerade an und probiers irgenwie umzusetzen.



  • Guten Morgen,
    habe hier einfach mal das probiert:

    void CXMLTestDlg::DisplayChildren(MSXML2::IXMLDOMNodePtr pParent)
    {
    	DisplayChild(pParent);
    
    	MSXML2::IXMLDOMNodePtr pChild;
    	for (pChild= pParent->firstChild; NULL != pChild; pChild = pChild->nextSibling)
    	{
    			pChild = pChild->attributes;
    			DisplayChildren(pChild);
    	}	
    }
    

    Habe mal so probiert an die Attribute ranzukommen.
    Kompiliert wird auch ohne zu meckern, aber beim Ausführen springt er dann in irgendson standarterzeugtes Blatt und meldet ne unbehandelte Ausnahme... 😕
    Würd mich freuen, wenn vielleicht mal jemand nen Stück Code hätte...
    Gruß Janinoe



  • Hallo,
    habs jetzt mit Hilfe eines XPath-Ausdruck hinbekommen.
    Vielen Dank für eure Hilfe. 👍
    Gruß Janinoe



  • Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum MFC (Visual C++) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


Anmelden zum Antworten