Xerces-C Intro:
The Apache project's Xerces-C libraries support the DOM approach to XML parsing.
The entire XML file is imported into memory and the data is held as nodes in a data tree which can be traversed for information.
The Xerces-C C++ parser home page: http://xml.apache.org/xerces-c/
Compiling Xerces-C:
- Go to your working directory. i.e.: cd /home/user-1/src
- Download Xerces-C 2.7.0 source from the Apache archive.
- Unpack the downloaded file: tar -xzf xerces-c-src_2_7_0.tar.gz
- Set the XERCESCROOT environment variable to the directory which contains the source code: (bash shell example)
export XERCESCROOT=/home/user-id/src/xerces-c-src_2_7_0
- Go to source directory: cd xerces-c-src_2_7_0/src/xercesc
- Run script which runs "configure": runConfigure -plinux -cgcc -xg++ -C--prefix=/opt/ApacheXML
- Build: make
- Install: make install
[Potential Pitfall]:
If installing as root (required when installing to directory paths like /opt and /usr), remember that root also requires the environment variable XERCESCROOT. Possible error:
-
make -C /obj install
make: *** /obj: No such file or directory. Stop.
make: *** [install] Error 2
Options for "
runConfigure":
Option |
Description |
-h |
Help |
-p platform-name |
Specify: aix, beos, linux, freebsd,
netbsd, solaris, hp-10, hp-11, openserver, unixware, os400, 0s390,
irix, ptx, tru64, macosx, cygwin, gnx, interix, mingw-msys
Required. No default.
Sets Makefile environment variable. i.e. PLATFORM=LINUX |
-c compiler |
Choices: gcc, cc, xlc_r, icc, icpc, ecc
Default=cc
Sets Makefile environment variable CC |
-x C++_compiler |
Chose: g++, CC, aCC, xlC_r, aCCOS, xlC_rv5compat, QCC
Default g++
Sets Makefile environment variable CXX |
-d |
Build debug version |
-m message-header |
Choices: inmem, icu, MsgFile, iconv
Default: inmem
Sets Makefile environment variable MESSAGELOADER used by Xerces. |
-n net-accessor |
Choices: fileonly, libwww, socket, native
Default: socket
Sets Makefile environment variable NETACCESSOR |
-t transcoder |
Choices: icu, Iconv400, uniconv390, IconvFBSD, IconvGNU, native
Default: native
Sets Makefile environment variable: TRANSCODER |
-r thread-option |
Choices: pthread, dce (AIX, HP-11, Solaris), spoc (IRIX), none
Default: pthread
Sets Makefile environment variable: THREADS |
-b bits-to-build |
Choices: 64, 32
Default: 32
Sets Makefile environment variable: BITSTOBUILD |
-l extra-linker-options |
Sets Makefile environment variable: LDFLAGS |
-z compiler-options |
|
-C configure-options |
Example: -C--prefix=/opt |
-P |
Install prefix |
This will install development files such as include header files and libraries in "/opt" so compiler flags and linker flags are required:
- Compiler flags: -I/opt/include
- Linker flags: -L/opt/lib -lxerces-c
Creating an RPM for Xerces-C libraries:
The downloaded gzipped tar file can be used to generate an RPM:
rpmbuild -ta xerces-c-src_2_7_0.tar.gz
[Potential Pitfall]: RHEL6+ rpmbuild failure
If you get the following error running the command
rpmbuild -ta xerces-c-src_2_7_0.tar.gz
error: line 13: Unknown tag: Copyright: Apache
This error was found using RHEL6 which uses a revised version of
rpmbuild from that when 2.7.0 was released.
Fix:
- Un-tar: tar xzf xerces-c-src_2_7_0.tar.gz
- Edit file xerces-c-src_2_7_0/xerces-c.spec
Change line 13 from:
Copyright: Apache
to:
License: Apache
- Re-tar: tar czf xerces-c-src_2_7_0.tar.gz xerces-c-src_2_7_0
- Build RPM: rpmbuild -ta xerces-c-src_2_7_0.tar.gz
[Potential Pitfall]: If you download the package
"
xerces-c-current.tar.gz", you may have to rename it to make it work. The error message will give you a clue as to what to name it.
In this example:
mv xerces-c-current.tar.gz xerces-c-src_2_7_0.tar.gz
Then execute the "
rpmbuild" command.
[Potential Pitfall]: If building as a Linux user, you will have to open up the directory permissions of /use/src/redhat/... or build as root user.
[Potential Pitfall]: This did not work with Red Hat Enterprise 5. (RHEL4 and 2.7.0 ok. RHEL5 and 3.0.1 ok. RHEL5 and 2.7.0 not ok) In this case I just downloaded the prebuild RPMs from http://pkgs.repoforge.org/xerces-c/
Results of
rpmbuild -ta xerces-c-src_2_7_0.tar.gz
Red Hat Enterprise 6.3 RPMs:
Wrote: /home/user1/rpmbuild/SRPMS/xerces-c-2.7.0-3.src.rpm
Wrote: /home/user1/rpmbuild/RPMS/x86_64/xerces-c-2.7.0-3.x86_64.rpm
Wrote: /home/user1/rpmbuild/RPMS/x86_64/xerces-c-devel-2.7.0-3.x86_64.rpm
Wrote: /home/user1/rpmbuild/RPMS/x86_64/xerces-c-doc-2.7.0-3.x86_64.rpm
Wrote: /home/user1/rpmbuild/RPMS/x86_64/xerces-c-debuginfo-2.7.0-3.x86_64.rpm
or this generates the RHEL5 RPM packages:
- /usr/src/packages/RPMS/i586/xerces-c-2.7.0-3.i586.rpm
- /usr/src/packages/RPMS/i586/xerces-c-devel-2.7.0-3.i586.rpm
- /usr/src/packages/RPMS/i586/xerces-c-doc-2.7.0-3.i586.rpm
or Red Hat Enterprise Linux 4 RPMs:
- /usr/src/redhat/RPMS/i386/xerces-c-2.7.0-3.i386.rpm
- /usr/src/redhat/RPMS/i386/xerces-c-devel-2.7.0-3.i386.rpm
- /usr/src/redhat/RPMS/i386/xerces-c-debuginfo-2.7.0-3.i386.rpm
- /usr/src/redhat/RPMS/i386/xerces-c-doc-2.7.0-3.i386.rpm
(Cleanup:
rm -Rf /var/tmp/xerces-c-root /usr/src/redhat/BUILD/xerces-c-src2_7_0)
or (Fedora Core 3 x86_64)
- /usr/src/redhat/SRPMS/xerces-c-2.7.0-3.src.rpm
- /usr/src/redhat/RPMS/x86_64/xerces-c-2.7.0-3.x86_64.rpm
- /usr/src/redhat/RPMS/x86_64/xerces-c-devel-2.7.0-3.x86_64.rpm
- /usr/src/redhat/RPMS/x86_64/xerces-c-doc-2.7.0-3.x86_64.rpm
- /usr/src/redhat/RPMS/x86_64/xerces-c-debuginfo-2.7.0-3.x86_64.rpm
Depending on your distribution and platform.
Install the RPMs with the command: rpm -ivh xerces-c-2.7.0-3.i586.rpm xerces-c-devel-2.7.0-3.i586.rpm xerces-c-doc-2.7.0-3.i586.rpm
Installing the RPM will place files in:
- Xerces-c RPM:
- Xerces-c doc RPM: /usr/share/xerces-c/
- Xerces-c devel RPM:
- /usr/include/xerces-c/
- /usr/share/doc/packages/xerces-c-doc/
Because the development libraries and include files are
located in the regular system areas expected by the compiler, the only
linker flag required is "-lxerces-c"
Programming with Xerces-C:
XML file:
sample.xml
01 | <? xml version = "1.0" encoding = "UTF-8" standalone = "no" ?> |
07 | </ ApplicationSettings > |
Include file:
parser.hpp
08 | #include <xercesc/dom/DOM.hpp> |
09 | #include <xercesc/dom/DOMDocument.hpp> |
10 | #include <xercesc/dom/DOMDocumentType.hpp> |
11 | #include <xercesc/dom/DOMElement.hpp> |
12 | #include <xercesc/dom/DOMImplementation.hpp> |
13 | #include <xercesc/dom/DOMImplementationLS.hpp> |
14 | #include <xercesc/dom/DOMNodeIterator.hpp> |
15 | #include <xercesc/dom/DOMNodeList.hpp> |
16 | #include <xercesc/dom/DOMText.hpp> |
18 | #include <xercesc/parsers/XercesDOMParser.hpp> |
19 | #include <xercesc/util/XMLUni.hpp> |
38 | void readConfigFile(std::string&) throw (std::runtime_error); |
40 | char *getOptionA() { return m_OptionA; }; |
41 | char *getOptionB() { return m_OptionB; }; |
44 | xercesc::XercesDOMParser *m_ConfigFileParser; |
52 | XMLCh* TAG_ApplicationSettings; |
C++ Program file:
parser.cpp
007 | #include <sys/types.h> |
014 | using namespace xercesc; |
023 | GetConfig::GetConfig() |
027 | XMLPlatformUtils::Initialize(); |
029 | catch ( XMLException& e ) |
031 | char * message = XMLString::transcode( e.getMessage() ); |
032 | cerr << "XML toolkit initialization error: " << message << endl; |
033 | XMLString::release( &message ); |
039 | TAG_root = XMLString::transcode( "root" ); |
040 | TAG_ApplicationSettings = XMLString::transcode( "ApplicationSettings" ); |
041 | ATTR_OptionA = XMLString::transcode( "option_a" ); |
042 | ATTR_OptionB = XMLString::transcode( "option_b" ); |
044 | m_ConfigFileParser = new XercesDOMParser; |
053 | GetConfig::~GetConfig() |
057 | delete m_ConfigFileParser; |
058 | if (m_OptionA) XMLString::release( &m_OptionA ); |
059 | if (m_OptionB) XMLString::release( &m_OptionB ); |
063 | XMLString::release( &TAG_root ); |
065 | XMLString::release( &TAG_ApplicationSettings ); |
066 | XMLString::release( &ATTR_OptionA ); |
067 | XMLString::release( &ATTR_OptionB ); |
071 | cerr << "Unknown exception encountered in TagNamesdtor" << endl; |
078 | XMLPlatformUtils::Terminate(); |
080 | catch ( xercesc::XMLException& e ) |
082 | char * message = xercesc::XMLString::transcode( e.getMessage() ); |
084 | cerr << "XML ttolkit teardown error: " << message << endl; |
085 | XMLString::release( &message ); |
098 | void GetConfig::readConfigFile(string& configFile) |
099 | throw ( std::runtime_error ) |
103 | struct stat fileStatus; |
106 | int iretStat = stat(configFile.c_str(), &fileStatus); |
109 | if ( errno == ENOENT ) |
110 | throw ( std::runtime_error( "Path file_name does not exist, or path is an empty string." ) ); |
111 | else if ( errno == ENOTDIR ) |
112 | throw ( std::runtime_error( "A component of the path is not a directory." )); |
113 | else if ( errno == ELOOP ) |
114 | throw ( std::runtime_error( "Too many symbolic links encountered while traversing the path." )); |
115 | else if ( errno == EACCES ) |
116 | throw ( std::runtime_error( "Permission denied." )); |
117 | else if ( errno == ENAMETOOLONG ) |
118 | throw ( std::runtime_error( "File can not be read\n" )); |
123 | m_ConfigFileParser->setValidationScheme( XercesDOMParser::Val_Never ); |
124 | m_ConfigFileParser->setDoNamespaces( false ); |
125 | m_ConfigFileParser->setDoSchema( false ); |
126 | m_ConfigFileParser->setLoadExternalDTD( false ); |
130 | m_ConfigFileParser->parse( configFile.c_str() ); |
133 | DOMDocument* xmlDoc = m_ConfigFileParser->getDocument(); |
137 | DOMElement* elementRoot = xmlDoc->getDocumentElement(); |
138 | if ( !elementRoot ) throw (std::runtime_error( "empty XML document" )); |
143 | DOMNodeList* children = elementRoot->getChildNodes(); |
144 | const XMLSize_t nodeCount = children->getLength(); |
148 | for ( XMLSize_t xx = 0; xx < nodeCount; ++xx ) |
150 | DOMNode* currentNode = children->item(xx); |
151 | if ( currentNode->getNodeType() && |
152 | currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) |
155 | DOMElement* currentElement |
156 | = dynamic_cast < xercesc::DOMElement* >( currentNode ); |
157 | if ( XMLString::equals(currentElement->getTagName(), TAG_ApplicationSettings)) |
161 | const XMLCh* xmlch_OptionA |
162 | = currentElement->getAttribute(ATTR_OptionA); |
163 | m_OptionA = XMLString::transcode(xmlch_OptionA); |
165 | const XMLCh* xmlch_OptionB |
166 | = currentElement->getAttribute(ATTR_OptionB); |
167 | m_OptionB = XMLString::transcode(xmlch_OptionB); |
174 | catch ( xercesc::XMLException& e ) |
176 | char * message = xercesc::XMLString::transcode( e.getMessage() ); |
177 | ostringstream errBuf; |
178 | errBuf << "Error parsing file: " << message << flush; |
179 | XMLString::release( &message ); |
188 | string configFile= "sample.xml" ; |
192 | appConfig.readConfigFile(configFile); |
194 | cout << "Application option A=" << appConfig.getOptionA() << endl; |
195 | cout << "Application option B=" << appConfig.getOptionB() << endl; |
Compile:
- RPM installed: g++ -g -Wall -pedantic -lxerces-c parser.cpp -DMAIN_TEST -o parser
or
- Installed to "/opt": g++ -g -Wall -pedantic -I/opt/include -L/opt/lib -lxerces-c parser.cpp -DMAIN_TEST -o parser
Run: parser
Application option A=10
Application option B=24
Links:

Books:
 |
Professional XML Development with Apache Tools : Xerces, Xalan, FOP, Cocoon, Axis, Xindice
by Theodore W. Leung
ISBN #0764543555, Wrox Press
|
|