Вы находитесь на странице: 1из 3

1/4/2016

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) {

}
}

if ((!strcmp(cur->name, "Project")) && (cur->ns == ns)) {


ret->projectID = xmlGetProp(cur, "ID");
if (ret->projectID == NULL) {
fprintf(stderr, "Project has no ID\n");
}
}
if ((!strcmp(cur->name, "Application")) && (cur->ns == ns))
ret->application = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if ((!strcmp(cur->name, "Category")) && (cur->ns == ns))
ret->category = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if ((!strcmp(cur->name, "Contact")) && (cur->ns == ns))
ret->contact = parsePerson(doc, ns, cur);
cur = cur->next;

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

Вам также может понравиться