webForumDet fria alternativet

XML Parser

18 svar · 538 visningar · startad av SPiN

SPiNMedlem sedan mars 20007 896 inlägg
#1

Någon som vet var man kan hitta en stabil XML-klass för C++? Gärna DOM XML...

------------------
SPiN, bjorne.w@telia.com

-- They pretend to pay me, I pretend to work --

developerMedlem sedan aug. 2001458 inlägg
#2

För Windows finns MSXML, som stöder både DOM och SAX. Se http://msdn.microsoft.com/xml

SPiNMedlem sedan mars 20007 896 inlägg
#3

Finns det någon sida där man kan hitta info om hur man använder MSXML, eller har du kanske lust att visa ett par exempel? :q :)

------------------
SPiN, bjorne.w@telia.com

-- They pretend to pay me, I pretend to work --

developerMedlem sedan aug. 2001458 inlägg
#4

Det finns en del exempel i MSDN, klicka runt i vänsterkolumnen lite bland olika ämnena från http://msdn.microsoft.com/xml . En del samples finns också finns på: http://msdn.microsoft.com/downloads/samples/internet/default.asp?url=/downloads/samples/internet/xml/c++_samples/default.asp?frame=true
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnxml/html/sax2jumpstart.asp?frame=true

Vad är du ute efter? Ska du lära dig lite allmänt eller har du nåt speciellt mål? Vilket språk?

Under året kommer VS7 släppas, där finns ett otroligt bra XML-stöd, och har du tillgång till betan av VS7 rekommenderar jag att du tittar där.

SPiNMedlem sedan mars 20007 896 inlägg
#5

Ok, tack för länkarna!

Vad är du ute efter? Ska du lära dig lite allmänt eller har du nåt speciellt mål? Vilket språk?

1. Jag är ute efter att kunna skapa, editera och se över mina XML-filer med C++, så att jag kan föra över information mellan olika system.

2. Jag vill lära mig allt om C++ och XML :)

3. C++ såklart! :e

------------------
SPiN, bjorne.w@telia.com

-- They pretend to pay me, I pretend to work --

developerMedlem sedan aug. 2001458 inlägg
#6

När det gäller att överföra data mellan olika system kan SOAP vara något för dig. Kort är det ett protokoll för att skicka objekt över exempelvis http. Standarden finns på http://www.w3.org/TR/SOAP . För VC6 finns SOAP toolkit att tillgå. Enklast är att titta på .Net webservices (ASP.Net), där SOAP är en fundamental del. Läs i MSDN eller på http://www.gotdotnet.com .

SPiNMedlem sedan mars 20007 896 inlägg
#7

Ok, upptagning av en jäääättegammal tråd nu då :)

Hur går jag tillväga om jag vill använda mig av MSXML med Dev-C++? Det är nämligen så att min dator med Visual Studio har, eh, trillat i golvet, och jag måste nu använda mig av hemdatorn där jag inte har tillgång till VS.

Jag tänkte att MSXML måste ju generera några .h och .cpp-filer nånstans, men jag har inte lyckats hitta dom om dom verkligen finns.

Går det att använda Dev-C++ med MSXML-parsern?

------------------
SPiN, bjorne.w@telia.com

-- Tekniska framsteg är som en yxa i händerna på en kriminell galning / Albert Einstein --

SPiNMedlem sedan mars 20007 896 inlägg
#8

Hmm, när jag kollade igenom länkarna på MSDN hittade jag följande lilla kodbit:
<font size="1" face="Verdana, Arial, Helvetica, sans-serif">Kod:<font size="1" face="Verdana, Arial, Helvetica, sans-serif" color="#666600">
#import <msxml3.dll> raw_interfaces_only
using namespace MSXML2;
...

Tänkte testa den nu, har inte hunnit göra det, men var ska jag lägga msxml3.dll? Spelar det någon roll? Det är ju registrerad på min dator, och då bör det väl inte spela nån roll?

Och vad betyder raw_interfaces_only? Jag har aldrig sett det förut...

------------------
SPiN, bjorne.w@telia.com

-- Tekniska framsteg är som en yxa i händerna på en kriminell galning / Albert Einstein --

SPiNMedlem sedan mars 20007 896 inlägg
#9

För intresserade lägger jag fram de här intressanta artiklarna/sidorna som behandlar C++ och XML:
Artikel @ IBM developerWorks
Parser & info @ IBM alphaWorks
XML-klass @ codeProject

Dock kvarstår mina frågor... :)

------------------
SPiN, bjorne.w@telia.com

-- Tekniska framsteg är som en yxa i händerna på en kriminell galning / Albert Einstein --

developerMedlem sedan aug. 2001458 inlägg
#10

Jag rekommenderar att du laddar hem SDK:t för XML-parsern. Sedan använder du filen "msxml2.h" som följer med. Den inkluderar du i ditt projekt.

Jag jobbar helst med ATL-pekare (CComPtr), se exempelvis http://www.endurasoft.com/vcd/msxml1.htm eller http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncdev00/html/vc00k1.asp .

raw_interfaces_only betyder att man inte ska generera smart-pointer-wrapper-klasser. (Som är ett alternativ till ATL-smartpekarna jag nämnde)

SPiNMedlem sedan mars 20007 896 inlägg
#11

Tack för all din hjälp, developer! Du är ju kung! :o :D

------------------
SPiN, bjorne.w@telia.com

-- Tekniska framsteg är som en yxa i händerna på en kriminell galning / Albert Einstein --

SPiNMedlem sedan mars 20007 896 inlägg
#12

Så kommer lärlingen krypande tillbaka till kungen för att be om råd, igen... :)

Jag försöker att kunna läsa/skriva XML med en klass jag gjort. Dock funkar den inte, kompilatorn klagar. Dessa felmeddelanden uppstår:
"'IXMLDOMDocument' : undeclared identifier"
"'CComPtr' : use of class template requires template argument list"

Här är en del av koden, fetmarkerad är raden som det blir fel på.

<font size="1" face="Verdana, Arial, Helvetica, sans-serif">Kod:<font size="1" face="Verdana, Arial, Helvetica, sans-serif" color="#666600">
#ifndef CXMLER_H
#define CXMLER_H

#include <atlbase.h>
#include <msxml.h>

class CXmler {
    private:
        CComPtr<IXMLDOMDocument> xmlDoc;
    public:
...
};

#endif

Vad kan jag göra för fel? :q

------------------
SPiN, bjorne.w@telia.com

-- Man vinner inte silver, man förlorar guld --

developerMedlem sedan aug. 2001458 inlägg
#13

Man kommer långt på smicker :)

Du använder <msxml.h>. Du borde istället ladda hem XML Parser SDK:t från MSDN och använda <msxml2.h>. Se http://msdn.microsoft.com/downloads/sample.asp?url=/msdn-files/027/000/542/msdncompositedoc.xml

Installera detta så får du lite filer i C:\Program Files\Microsoft XML Parser SDK\inc. Lägg förslagsvis bland dina andra header-filer i Visual Studios include-katalog.

[Redigerat av developer den 03 dec 2001]

SPiNMedlem sedan mars 20007 896 inlägg
#14

Man kommer långt på smicker

Jag vet :e

Hmm, jag har ju redan tvåan - tänkte inte på att jag använde ettan. Men i de exempel som jag hittat, har de använt sig av ettan men ändå liknande kod som jag har. Wierd. Aja, jag provar!

Tack ännu en gång!

------------------
SPiN, bjorne.w@telia.com

-- Man vinner inte silver, man förlorar guld --

SPiNMedlem sedan mars 20007 896 inlägg
#15

Får jag fråga en till sak? Varför använder du ATL-pekare? Är det bättre på något sätt? Om man använder MSXML's egna klasser ser allt nästintill likadant ut, tycker jag. Det måste finnas en orsak?

------------------
SPiN, bjorne.w@telia.com

-- Man vinner inte silver, man förlorar guld --

developerMedlem sedan aug. 2001458 inlägg
#16

Mycket en smaksak. Vad man än väljer är ok tycker jag.

I fallet ATL är det ju vanliga C++ templates man använder och några få enkla hjälpklasser för COM-interfacen. Man slipper böket med COMs råa BSTR-strängar, och använder istället en enkel men bra wrapper CComBSTR.

I fallet kompilator-genererade smart pointers automat-genereras säkert några tusen rader wrapper-klasser åt dig. Jag tycker det känns som en tveksam lösning även om det fungerar. Man blir dessutom påtvingad sträng-klassen _bstr_t som inte här 100-procentigt bra i mina ögon. Där finns inget alternativ i och med att de kompilator-genererade filerna kräver detta. (I fallet ATL kan man välja att använda råa BSTR, ATLs CComBSTR, eller en helt egen klass).

Felhanteringen i ATL-varianten bygger på att man hela tiden undersöker HRESULT som metoderna returnerar. De wrappers som kompilatorn genererar undersöker HRESULTen åt dig och kastar istället exceptions. Om man använder com-interface, som exempelvis MSXML, när man implementerar ett annat COM-interface är det i mitt tycke bättre att använda ATL. Annars måste man i varje funktion fånga exceptions som kan kastas och göra om dessa till HRESULT-returvärden. Använder man ATL slipper man gå omvägen över exceptions.

Jag tycker annars exceptions är ett bra sätt att hantera fel i C++ kod. Overheaden är liten så länge man är i normalfallet, och det gör koden lätt att överblicka samtidigt som felhanteringen är smidig. Men just i det här fallet föredrar jag returkoder.

Möjligen har de kompilator-genererade klasserna en lägre inlärningströskel. Jag tror många börjar med dessa, men när man känner sig hemma på COM är ATL ett kraftfullare alternativ.

Jag tycker också att debuggningen är trevligare när man använder ATL än att behöva steppa in i kompilator-gerererade wrapper-klasserna.

BeatboxMedlem sedan okt. 20013 217 inlägg
#17

Plus att CComPtr håller reda på referensräkning så du kan inte tilldela pekaren två gånger, då kastas en exception.

// BeatBox

------------------
"Mörkrets gärningar, förekommer även på dagen"

Sixten Landby

SPiNMedlem sedan mars 20007 896 inlägg
#18

Tack för utlägget! Nu märker jag hur lite jag egentligen kan :e

SPiNMedlem sedan mars 20007 896 inlägg
#19

Nu är jag här igen...

Jag får det verkligen inte att funka, och snart är det deadline. x(

Har suttit hela jäkla helgen, men fortfarande är det något som inte funkar.

Felmeddelandena är:
'IXMLDOMDocument2' : Cannot instantiate abstract class due following... <- Fel 1

'int __cdecl CoUninitialize(void)' : overloaded function differs only by return type from 'void __stdcall CoUninitialize(void)' <- Fel 2

'CoUninitialize' : redefinition; different type modifiers <- Fel 3

Här är min fil:

#ifndef _SODA_CXMLER_H
#define _SODA_CXMLER_H

#include "includes.h"
#include "StringStack.h"

typedef VARIANT_BOOL vbool;
typedef IXMLDOMDocument2 XmlerDocument;
typedef IXMLDOMNode XmlerNode;
typedef IXMLDOMElement XmlerElem;
typedef IXMLDOMNodeList XmlerNodeList;
typedef BSTR XmlerString;

HRESULT hResult = CoInitialize ( NULL );

class CXmler { // Klass som hanterar XML-filerna
	private:
		XmlerDocument	xmlDoc; [b]// <-- Här kommer fel 1![/b]		
		string			xmlFile;
		StringStack		xmlStack;
		

		bool ExcHandl ( HRESULT hResult, char* exceptionError ) { // Funktion för att hantera exceptions från HRESULT
			if ( FAILED ( hResult ) ) {
				cout << "\n\n*** Error ***\n";
				cout << exceptionError;
				
				
				exit ( 1 );
			}
			
			
			return true;
		}
		void ExcHandl ( char* exceptionError ) { // Funktion för att hantera exceptions
			cout << "\n\n*** Error ***\n";
			cout << exceptionError;
			
			
			exit ( 1 );
		}
	public:
		CXmler () { // Konstruktor, sätter XML-filen från default (C:\CXmler.xml)
			xmlFile.assign ( "C:\\CXmler.xml" );
		}
		CXmler ( char* newXmlFile ) { // Konstruktor, sätter angiven XML-fil
			xmlFile.assign ( newXmlFile );
		}
		CXmler ( string newXmlFile ) { // Konstruktor, sätter angiven XML-fil
			xmlFile.assign ( newXmlFile.c_str () );
		}
		~CXmler () { // Destruktor
		}
		
		
		void Open () { // Öppna dokumentet
			if ( !xmlFile == NULL ) {
				Open ( xmlFile.c_str () );
			}
			else {
				ExcHandl ( "Du har inte angett någon XML-fil att öppna"); // Filen hittades inte
			}
		}
		
		
		void Open ( char* newXmlFile ) { // Öppna en ny XML-fil om filen hittas
			vbool vB = false;
			
			
			ExcHandl ( xmlDoc.CoCreateInstance ( __uuidof ( DOMDocument ) ), "Kunde inte skapa XML-parser" );
			ExcHandl ( xmlDoc->load ( newXmlFile, &vB ), "Kunde inte öppna den angivna XML-filen" );
			
			
			if ( !vB ) {
				ExcHandl ( "Kunde inte öppna den angivna XML-filen" ); // Filen kunde inte öppnas
			}
		}
		
		
		void Open ( string newXmlFile ) { // Skickar vidare till Open ( char* )
			Open ( newXmlFile.c_str () );
		}
		
		
		void Save () { // Spara XML-filen
			Save ( xmlFile.c_str () );
		}
		
		
		void Save ( char* toXmlFile ) { // Spara till angiven XML-fil
			ExcHandl ( xmlDoc->save ( toXmlFile ), "Kunde inte spara till den angivna XML-filen" );
		}
		
		
		void Save ( string toXmlFile ) { // Spara till angiven XML-fil
			Save ( toXmlFile.c_str () );
		}
		
		
		StringStack getData ( char* cPath, char* cCompareElem, char* cCompareName ) { // Hämta data från XML-dokumentet
			XmlerElem		xmlElem;
			XmlerNode		xmlNode;
			XmlerNodeList	xmlList;
			
			
			ExcHandl ( xmlDoc->selectSingleNode ( cPath, &xmlNode ), "Kunde inte hitta den angivna pathen" );
			
			
			if ( xmlNode.p == NULL ) {
				ExcHandl ( "Kunde inte hitta den angivna pathen" );
			}
			
			
			xmlElem = xmlNode;
			
			
			if ( xmlElem.p == NULL ) {
				ExcHandl ( "Kunde inte konvertera mellan element och node vid parsning" );
			}
			
			
			ExcHandl ( xmlElem->getElementByTagName ( cCompareElem, &xmlList ), "Kunde inte hitta de angivna elementen" );
			
			
			if ( xmlList->length < 1 ) {
				ExcHandl ( "Det angivna elementet hittades inte i pathen" );
			}
			
			
			xmlStack.set ( xmlList->length );
			
			
			while ( ExcHandl ( xmlList->nextNode ( &xmlNode ), "Ett okänt fel inträffade" ) ) {
				if ( xmlNode->nodeName == cCompareName ) {
					xmlStack.push ( xmlNode->text );
				}
			}
			
			
			return xmlStack;
		}
		string getData ( string sPath, string sCompareElem, string sCompareName ) { // Hämta data från XML-filen
			return getData ( sPath.c_str (), sCompareElem.c_str (), sCompareName.c_str () );
		}

		string getNodeValue ( char* cPath ) { // Hämta nod-värde från angiven path
			XmlerNode		xmlNode;
			XmlerString		xmlText;
			string			xmlValue;

			ExcHandl ( xmlDoc->selectSingleNode ( cPath, &xmlNode ), "Kunde inte hitta den angivna noden" );

			if ( xmlNode.p == NULL ) {
				ExcHandl ( "Kunde inte hitta den angivna noden" );
			}

			ExcHandl ( xmlNode->get_text ( &xmlText ), "Kunde inte hämta texten från den angivna noden" );

			xmlValue.assign ( xmlText.value );
			return xmlValue;
		}
		string getNodeValue ( string sPath ) { // Hämta nod-värde från angiven path
			return getNodeValue ( sPath.c_str () );
		}

		void setNodeValue ( char* cPath, char* cValue ) { // Sätt nytt värde på angiven nod
			XmlerNode xmlNode;

			ExcHandl ( xmlDoc->selectSingleNode ( cPath, &xmlNode ), "Kunde inte hitta den angivna noden" );

			if ( xmlNode.p == NULL ) {
				ExcHandl ( "Kunde inte hitta den angivna noden" );
			}

			xmlNode->text = cValue;
		}
		void setNodeValue ( string sPath, string sValue ) { // Sätt värde på nod
			setNodeValue ( sPath.c_str (), sValue.c_str () );
		}
};

CoUninitialize (); [b]// <- Här kommer fel 2 & 3![/b]

#endif

Hoppas någon ( developer? :) ) har några tips att ge!

------------------
SPiN, bjorne.w@telia.com

-- En ask vet jag stånda - den Yggdrasil heter, ett väldigt träd överöst av vita sanden. --

[Redigerat av SPiN den 09 dec 2001]

135 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
133 ms — hämta tråd, inlägg och bilagor (db)