Академический Документы
Профессиональный Документы
Культура Документы
A real example
Gnome2Logo
Action
against
software
patents
DeveloperMenu
Search...
MainMenu
Reference
Manual
CodeExamples
XMLGuidelines
Tutorial
TheReader
Interface
ChangeLog
XSLT
Pythonand
bindings
libxml2
architecture
Thetreeoutput
TheSAXinterface
Memory
Management
I/OInterfaces
Theparser
interfaces
Entitiesorno
entities
Namespaces
Upgrading1.x
code
Threadsafety
DOMPrinciples
Arealexample
flatpage,
stylesheet
APIIndexes
Alphabetic
Constructors
Functions/Types
Modules
Symbols
Relatedlinks
Mailarchive
XSLTlibxslt
TheXMLCparserandtoolkit
ofGnome
Arealexample
Hereisarealsizeexample,wheretheactualcontentoftheapplicationdataisnotkeptin
theDOMtreebutusesinternalstructures.Itisbasedonaproposaltokeepadatabaseof
jobsrelatedtoGnome,withanXMLbasedstoragestructure.HereisanXMLencoded
jobsbase:
<?xml version="1.0"?>
<gjob:Helping xmlns:gjob="http://www.gnome.org/some-location">
<gjob:Jobs>
<gjob:Job>
<gjob:Project ID="3"/>
<gjob:Application>GBackup</gjob:Application>
<gjob:Category>Development</gjob:Category>
<gjob:Update>
<gjob:Status>Open</gjob:Status>
<gjob:Modified>Mon, 07 Jun 1999 20:27:45 -0400 MET DST</gjob:Modified>
<gjob:Salary>USD 0.00</gjob:Salary>
</gjob:Update>
<gjob:Developers>
<gjob:Developer>
</gjob:Developer>
</gjob:Developers>
<gjob:Contact>
<gjob:Person>Nathan Clemons</gjob:Person>
<gjob:Email>nathan@windsofstorm.net</gjob:Email>
<gjob:Company>
</gjob:Company>
<gjob:Organisation>
</gjob:Organisation>
<gjob:Webpage>
</gjob:Webpage>
<gjob:Snailmail>
</gjob:Snailmail>
<gjob:Phone>
</gjob:Phone>
</gjob:Contact>
<gjob:Requirements>
The program should be released as free software, under the GPL.
</gjob:Requirements>
<gjob:Skills>
</gjob:Skills>
<gjob:Details>
A GNOME based system that will allow a superuser to configure
compressed and uncompressed files and/or file systems to be backed
up with a supported media in the system. This should be able to
perform via find commands generating a list of files that are passed
to tar, dd, cpio, cp, gzip, etc., to be directed to the tape machine
or via operations performed on the filesystem itself. Email
notification and GUI status display very important.
</gjob:Details>
file:///home/christian/Desktop/libxml2-2.7.2/doc/example.html
1/3
1/4/2016
A real example
DOMgdome2
XMLDSigxmlsec
FTP
Windowsbinaries
Solarisbinaries
MacOsXbinaries
lxmlPython
bindings
Perlbindings
C++bindings
PHPbindings
Pascalbindings
Rubybindings
Tclbindings
BugTracker
</gjob:Job>
</gjob:Jobs>
</gjob:Helping>
WhileloadingtheXMLfileintoaninternalDOMtreeisamatterofcallingonlyacoupleof
functions,browsingthetreetogatherthedataandgeneratetheinternalstructuresis
harder,andmoreerrorprone.
Thesuggestedprincipleistobetolerantwithrespecttotheinputstructure.Forexample,
theorderingoftheattributesisnotsignificant,theXMLspecificationisclearaboutit.It's
alsousuallyagoodideanottodependontheorderofthechildrenofagivennode,unless
itreallymakesthingsharder.Hereissomecodetoparsetheinformationforaperson:
/*
* A person record
*/
typedef struct person {
char *name;
char *email;
char *company;
char *organisation;
char *smail;
char *webPage;
char *phone;
} person, *personPtr;
/*
* And the code needed to parse it
*/
personPtr parsePerson(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {
personPtr ret = NULL;
DEBUG("parsePerson\n");
/*
* allocate the struct
*/
ret = (personPtr) malloc(sizeof(person));
if (ret == NULL) {
fprintf(stderr,"out of memory\n");
return(NULL);
}
memset(ret, 0, sizeof(person));
/* We don't care what the top level element name is */
cur = cur->xmlChildrenNode;
while (cur != NULL) {
if ((!strcmp(cur->name, "Person")) && (cur->ns == ns))
ret->name = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if ((!strcmp(cur->name, "Email")) && (cur->ns == ns))
ret->email = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
cur = cur->next;
}
}
return(ret);
Hereareacoupleofthingstonotice:
Usuallyarecursiveparsingstyleisthemoreconvenientone:XMLdataisbynature
subjecttorepetitiveconstructsandusuallyexhibitshighlystructuredpatterns.
ThetwoargumentsoftypexmlDocPtrandxmlNsPtr,i.e.thepointertotheglobal
XMLdocumentandthenamespacereservedtotheapplication.Documentwide
informationareneededforexampletodecodeentitiesandit'sagoodcoding
practicetodefineanamespaceforyourapplicationsetofdataandtestthatthe
elementandattributesyou'reanalyzingactuallypertainstoyourapplicationspace.
Thisisdonebyasimpleequalitytest(cur>ns==ns).
Toretrievetextandattributesvalue,youcanusethefunctionxmlNodeListGetString
togatherallthetextandentityreferencenodesgeneratedbytheDOMoutputand
produceansingletextstring.
file:///home/christian/Desktop/libxml2-2.7.2/doc/example.html
2/3
1/4/2016
A real example
Hereisanotherpieceofcodeusedtoparseanotherlevelofthestructure:
#include <libxml/tree.h>
/*
* a Description for a Job
*/
typedef struct job {
char *projectID;
char *application;
char *category;
personPtr contact;
int nbDevelopers;
personPtr developers[100]; /* using dynamic alloc is left as an exercise */
} job, *jobPtr;
/*
* And the code needed to parse it
*/
jobPtr parseJob(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {
jobPtr ret = NULL;
DEBUG("parseJob\n");
/*
* allocate the struct
*/
ret = (jobPtr) malloc(sizeof(job));
if (ret == NULL) {
fprintf(stderr,"out of memory\n");
return(NULL);
}
memset(ret, 0, sizeof(job));
/* We don't care what the top level element name is */
cur = cur->xmlChildrenNode;
while (cur != NULL) {
}
}
return(ret);
Onceyouareusedtoit,writingthiskindofcodeisquitesimple,butboring.Ultimately,it
couldbepossibletowritestubberstakingeitherCdatastructuredefinitions,asetofXML
examplesoranXMLDTDandproducethecodeneededtoimportandexportthecontent
betweenCdataandXMLstorage.Thisisleftasanexercisetothereader:)
FeelfreetousethecodeforthefullCparsingexampleasatemplate,itisalsoavailable
withMakefileintheGnomeSVNbaseunderlibxml2/example
DanielVeillard
file:///home/christian/Desktop/libxml2-2.7.2/doc/example.html
3/3