Avatar billede superjma Nybegynder
04. juli 2004 - 13:01 Der er 12 kommentarer og
1 løsning

Xml-parsing

Hej

Jeg vil høre hvordan man parser(læser) et XML-dokument i C++?

Er der nogle gode referencer til hvordan man programmerer C++, på nettet? Jeg synes ikke der er så meget info/eksempler som er brugbare.
Avatar billede arne_v Ekspert
04. juli 2004 - 14:03 #1
XML er meget Java og .NET

Du skal have fat i en XML parser.

Jeg er meget glad for Xerces i Java udgaven.

Så selv uden at have prøvet den vil jeg anbefale Xerces i C++ udgaven:

http://xml.apache.org/xerces-c/index.html
Avatar billede superjma Nybegynder
04. juli 2004 - 17:59 #2
Jeg har installeret en Xerces XML-parser.

Mit problem er hvordan jeg skriver koden der parser det. Jeg kan ikke finde nogle eksempler.

Det tætteste jeg har fundet er flg. som dog ikke virker.
#include <xercesc/parsers/DOMParser.hpp>
#include <xalanc/XalanTransformer/XercesDOMWrapperParsedSource.hpp>

void parseWithXerces(  XalanTransformer &xalan,
                        const XSLTInputSource &xmlInput,
                        const XalanCompiledStylesheet* styleSheer,
                        const XSLTResultTarget &output,
                        XMLFileReporter &logFile)
{
        XercesDOMParser theParser;

        // Turn on validatiion and namespace support.
        theParser.setDoValidation(true);
        theParser.setDoNamespaces(true);
        // Parse the document
        theParser.parse(xmlInput);
        DOMDocument *theDOM = theParser.getDocument();
        theDOM->normalize();
        XercesDOMSupport theDOMSupport;
        XercesParserLiaison theParserLiaison;
        // Use the DOM to create a XercesDOMWrapperParsedSource,
        // which you can pass to the transform method.
        try
        {
                const XercesDOMWrapperParsedSource parsedSource(
                                theDOM,
                                theParserLiaison,
                                theDOMSupport,
                                XalanDOMString(xmlInput.getSystemId()));

                xalan.transform(parsedSource, stylesheet, output);
        }
        catch (....)
        {
                ...
        }
}
Avatar billede arne_v Ekspert
04. juli 2004 - 18:02 #3
Ifølge http://xml.apache.org/xerces-c/samples.html skulle der være et helt
sampels dir med en række eksempler.

Og der er også http://xml.apache.org/xerces-c/program.html
Avatar billede superjma Nybegynder
04. juli 2004 - 19:39 #4
Det er der skam også, men der er tale om filer på 500+ linier. Lidt svært at sætte sig ind i, når man først skal til at lære c++.

Havde håber at jeg kunne nøjes med at undersøge et lille eksempel på en 20-50 linier, som jeg så kunne tage udgangspunkt i ved construktionen af min egen parser.
Avatar billede arne_v Ekspert
04. juli 2004 - 19:55 #5
Jeg tror at XML parser er lidt halv tungt at lære C++ med.

Men jeg kan evt. godt prøve at lave et lille simpelt eksempel senere i aften.
Avatar billede superjma Nybegynder
04. juli 2004 - 20:11 #6
Det er desværre ved at gå op for mig. Men jeg skal lave et cgi-script der kan parse en XML-fil til en mysql-database.. Har kodet en lille smule C engang men ikke nok til at jeg kan huske så meget af det.. andet end at jeg havde lidt bøvl med pointere og chararrays.. Mener heldigvis at have hørt at C++ har String-objekter fremfor chararrays som jo sætter en begrænsning i kraft af en foruddefinition på størrelsen.
Avatar billede superjma Nybegynder
04. juli 2004 - 20:13 #7
Men du må meget gerne lave et lille eksempel. Så kan jeg hæve point-givningen..
Det skal helst være kort og muligt at tilgå tag'ne og attributterne efterhånden som man støder på dem. Gerne rekursivt, således at man hele tiden ved hvem parent er;-)
Avatar billede arne_v Ekspert
04. juli 2004 - 21:37 #8
Her er ihvertfald et super simpelt eksempel:

test.xml:

<?xml version="1.0" encoding="UTF-8"?>
<allf>
<f>1</f>
<f>2</f>
<f>3</f>
</allf>

dom.cpp:

#include <iostream>

using namespace std;

#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>

using namespace xercesc_2_5;

int main (int argc, char* args[])
{
    XMLPlatformUtils::Initialize();
    XercesDOMParser* parser = new XercesDOMParser();
    ErrorHandler* errHandler = (ErrorHandler*) new HandlerBase();
    parser->setErrorHandler(errHandler);
    parser->parse("test.xml");
    DOMDocument* doc = parser->getDocument();
    DOMNodeList* elms = doc->getElementsByTagName(L"f");
    for(int i=0; i < elms->getLength(); i++)
    {
        cout << XMLString::transcode(elms->item(i)->getFirstChild()->getNodeValue()) << endl;
    }
    delete parser;
    delete errHandler;
    return 0;
}

output:

1
2
3
Avatar billede arne_v Ekspert
04. juli 2004 - 22:02 #9
Her med en attribut:

test2.xml:

<?xml version="1.0" encoding="UTF-8"?>
<allf>
<f nr="1">a</f>
<f nr="2">bb</f>
<f nr="3">ccc</f>
</allf>

dom2.cpp:

#include <iostream>

using namespace std;

#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>

using namespace xercesc_2_5;

int main (int argc, char* args[])
{
    XMLPlatformUtils::Initialize();
    XercesDOMParser* parser = new XercesDOMParser();
    ErrorHandler* errHandler = (ErrorHandler*) new HandlerBase();
    parser->setErrorHandler(errHandler);
    parser->parse("test2.xml");
    DOMDocument* doc = parser->getDocument();
    DOMNodeList* elms = doc->getElementsByTagName(L"f");
    for(int i=0; i < elms->getLength(); i++)
    {
        cout << XMLString::transcode(((DOMElement *)elms->item(i))->getAttributeNode(L"nr")->getNodeValue()) << " "
            << XMLString::transcode(elms->item(i)->getFirstChild()->getNodeValue()) << endl;
    }
    delete parser;
    delete errHandler;
    return 0;
}

output:

1 a
2 bb
3 ccc
Avatar billede superjma Nybegynder
04. juli 2004 - 22:22 #10
Tusind tak for det.. det ser simpelt ud.

Jeg kan dog ikke kompilere det på min maskine.
Kompilerer med g++ -I/usr/include/mysql -I/usr/include/xercesc dom.cpp /usr/lib/libmysqlclient.a -lz -lssl -o dom
Mangler XercesDOMParser.hpp.. har ellers installeret libxerces21c102, libxerces25, libxerces1, libxerces1.6, libxerces1-dev, libxalan16 libxerces23 og xalan. (kører debian)

Jeg kan ligeledes ikke se hvordan man skal parse xml'en hvis den bliver mere kompleks, eller du ikke kender strukturen og antallet af niveauer.
Avatar billede arne_v Ekspert
04. juli 2004 - 22:26 #11
Har du XercesDOMParser.hpp på dit system ?

(find / -name XercesDOMParser.hpp)
Avatar billede arne_v Ekspert
04. juli 2004 - 22:28 #12
Du kan klare dybere strukturer ved at kalde getChildNodes på en node.

Men du skal nok vide et eller andet om formatet.

Du kan også skifte fra DOM til SAX.

Der er mange muligheder.
Avatar billede superjma Nybegynder
04. juli 2004 - 23:02 #13
Nej det er det der er problemet.

Jeg har netop opgivet, da jeg lige forsøgte i perl, som jeg heller ikke har nogen erfaring med men der nåede jeg rigtigt langt på meget kort tid.

Det er trods alt også et CGI-script. Det kører måske ikke helt lige så hurtigt... men det virker.

Undskyld ulejligheden:-(
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester