Problem mit ClientDataSet und XML - Unter DB auslesen?



  • Hallo Zusammen,
    ich habe ein kleines Problem mit ClientDataSet und einer XML Datei.

    Aktuell habe ich folgendes:

    XMLTransform1->SourceXmlFile = "text.xml";
    XMLTransform1->TransformationFile = "text.xtr";
    ClientDataSet1->XMLData = XMLTransform1->Data;
    

    Auf die Daten greife ich jetzt z.B. so zu:

    ClientDataSet1->FieldByName("address_country_id1")->AsString
    

    Das funktioniert soweit auch. Allerdings habe ich als letzte "Feld" order_item. Das wird mir als DATASET angezeigt. Darin befinden sich Artikeldaten. Mal ein Datensatz mal mehrere.

    Meine Frage ist jetzt, wie greife ich darauf zu? Wenn ich über order_item gehe bekomme ich als Wert nur "DATASET". Wenn ich über den Feldnamen gehe, der sich darin befindet bekomme ich die Meldung, dass es kein Feld mit dem Namen gibt.

    Kann mir da jemand helfen?



  • Ciao EPMS

    Um ein XML-Dokument aus zu lesen verwende ich die TXMLDocument Komponente. Wie man das ausliest viendest du in vielen Beispielen. Wenn du nicht weiter kommst, helfe ich dir gerne weiter.

    Gruss Renato



  • Hi Renato,
    danke für deinen Hinweis. Ich probiere es jetzt auch mit TXMLDocument. Klappt soweit auch ganz gut. Bis auf eine Kleinigkeit.
    Ich habe Felder in denen nichts steht.

    Wenn ich jetzt auf so eins z.B. mit:

    String Firma = XMLDaten->order_fulfiller_request[i]->order_fulfiller->customer_invoice->invoice_address->general->company;
    

    zugreifen möchte, bekomme ich die Fehlermeldung:

    Variante des Typs NULL konnte nich in Typ OleStr onvertiert werden

    Ich schäzte mal, es liegt daran das das Feld keinen Wert enthält. Aber wie kann ich das abfangen?

    Hast du sowas bei dir vielleicht auch gelöst?



  • Ciao EPMS

    Nein so geht es nicht. Ich kann dir erst Morgen ein Beispiel präsentieren. Such doch mal in den Codebeispielen. Dort hat es ein Beispiel wie die Komponente benutzt wird.

    Die XML-Datei ist wie ein Baum aufgebaut. Man muss sich von Ast zu Ast durcharbeiten. Danach kann man die Einzelnen Daten auslesen.

    Versuch es mal selbst sonst helfe ich dir morgen Abend weiter.

    Gruss Renato



  • Hi Renato,
    aktuell gehe ich über Doppelklick auf TXMLDocument und dann geht der Wizard auf. Dort habe ich nichts eingestellt und bin immer auf weiter. Danach habe ich eine neue .cpp Datei. Die habe ich in mein Projekt eingebunden und greife dann darauf zu.
    Das funktioniert soweit auch. Ich kann auf die Daten in der XMl mit

    String Firma = XMLDaten->order_fulfiller_request[i]->order_fulfiller->customer_invoice->invoice_address->general->company;
    

    zugreifen. Wenn hier in dem Beispiel in company etwas drin steht dann habe ich es in der variablen Firma.

    Die Fehlermeldung kommt halt nur, wenn company in der XML leer ist.



  • Ciao EPMS

    Da wurde die Komponente wohl umgebaut. Denn unter XE7 kann man die sie nicht mehr doppelklicken. Da muss man sich von Ast zu Ast durchangeln.

    Hir ein Programmausschnitt wie man eine XML-Datei öffnent und ausliest unter XE7.

    // Holt die Daten aus der XML Datei
    	_di_IXMLDocument xmld_person;
    	_di_IXMLNode node;
    	_di_IXMLNode knoten;
    	_di_IXMLNode kind;
    	int n_knoten{0};
    	int n_pos{0};
    	TStringList *str_text;
    	array<AnsiString, 12> str_opt;
    	AnsiString str_pdatei;
    
    	//nur nach Projekt fragen falls Projekt noch nicht geöffnet ist
    	if( str_projekt.IsEmpty() )
    	{
    		//Projekt öffnen
    			opd_person->Title += " öffnen";
    		if( opd_person->Execute() )
    		{
    			str_projekt = opd_person->FileName;
    		}
    	}
    
    	//Dateiname ermitteln und Daten Laden
    	str_pdatei = get_projektname( str_projekt );
    	str_pdatei += "_person.xml";
    	if( FileExists(str_pdatei) )
    	{
       	xmld_person = interface_cast<Xmlintf::IXMLDocument>(new TXMLDocument(NULL));
    		xmld_person->Active = true;
    
    		xmld_person->LoadFromFile(str_pdatei);
    
    		node = xmld_person->ChildNodes->FindNode("personendaten");
    		n_knoten = node->ChildNodes->Count;
    		strg_person->RowCount = n_knoten;
    		for(int n_x = 0; n_x < n_knoten ;n_x++)
    		{
    			knoten = node->ChildNodes->Get(n_x);
    			str_text = get_person(knoten);
    			strg_person->Rows[n_x] = str_text;
    		}
    		rechte();
    	}
    

    Gruss Renato



  • Hallo zusammen,

    vorweg, ich habe mir die Komponente damals unter Builder 2010 angeschaut, jedoch nie wirklich damit gearbeitet.
    Der "Wizard" welcher automatisch Code für die XML Datei generiert, gab es damals schon, er muß soweit ich mich erinnern kann nur anders gestartet werden (kein Doppelklick).

    Die Frage die sich hier doch stellt, ist was hast Du hier für einen Rückgabewert?

    XMLDaten->order_fulfiller_request[i]->order_fulfiller->customer_invoice->invoice_address->general->company;
    

    Nach der Fehlermeldung zu urteilen, vermute ich, daß es sich um einen VARIANT handelt.
    Um dein Problem zu umgehen, würde ich einfach den Rückgabewert auf NULL prüfen, und wenn dies nicht erfolgreich ist in die String Variable ablegen.
    Eventuell hat der VARIANT Typ selbst auch noch eine entsprechende Funktion zu bieten.

    MfG Stephan



  • Hallo Zusammen,
    danke für die Hilfe. Ich habe den Fehler gefunden. Das Problem war, dass die XML leider nicht gerade toll aufgebaut ist. Das Feld "Company" gibt es mal und mal nicht.

    Die Fehlermeldung bekomme ich dann natürlich an der Stelle, an der es das Feld überhaupt nicht gibt.



  • String Firma = XMLDaten->order_fulfiller_request[i]->order_fulfiller->customer_invoice->invoice_address->general->company;

    Das schaut auch nicht nach sicherem Code aus. Du greifst auf zig Zeiger nacheinander zu, ohne jemals zu prüfen, ob sie gültig sind.


Log in to reply