Xerces C++ - Load, read and save, alternatives?
Solution 1
A Sample for Saving xerces DOMDocument. Saving a Document with
DOMLSSerializer::write(const DOMNode* nodeToWrite, DOMLSOutput* const destination)
see code Example http://xerces.apache.org/xerces-c/domprint-2.html
DOMLSSerializer * theSerializer = impl->createLSSerializer();
DOMPrintFilter *myFilter = new DOMPrintFilter(DOMNodeFilter::SHOW_ELEMENT |
DOMNodeFilter::SHOW_ATTRIBUTE |
DOMNodeFilter::SHOW_DOCUMENT_TYPE);
theSerializer->setFilter(myFilter);
DOMLSOutput *theOutputDesc = ((DOMImplementationLS*)impl)->createLSOutput();
XMLFormatTarget *myFormTarget = new LocalFileFormatTarget(XMLString::transcode("C:\\target.xml"));
theOutputDesc->setByteStream(myFormTarget);
theOutputDesc->setEncoding(XMLString::transcode("ISO-8859-1"));
theSerializer->getDomConfig()->setParameter(XMLUni::fgDOMXMLDeclaration, true);
theSerializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
theSerializer->write(doc, theOutputDesc);
myFormTarget->flush();
delete myFormTarget;
theOutputDesc->release();
theSerializer->release();
And a example for Filter implementation. You can find this in DOMPrint example.
class DOMPrintFilter : public DOMLSSerializerFilter {
public:
DOMPrintFilter(ShowType whatToShow = DOMNodeFilter::SHOW_ALL);
~DOMPrintFilter(){};
virtual FilterAction acceptNode(const DOMNode*) const;
virtual ShowType getWhatToShow() const {return fWhatToShow;};
private:
// unimplemented copy ctor and assignement operator
DOMPrintFilter(const DOMPrintFilter&);
DOMPrintFilter & operator = (const DOMPrintFilter&);
ShowType fWhatToShow;
};
#include "DOMPrintFilter.hpp"
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/util/XMLString.hpp>
static const XMLCh element_person[]=
{
chLatin_p, chLatin_e, chLatin_r, chLatin_s, chLatin_o, chLatin_n, chNull
};
static const XMLCh element_link[]=
{
chLatin_l, chLatin_i, chLatin_n, chLatin_k, chNull
};
DOMPrintFilter::DOMPrintFilter(ShowType whatToShow)
:fWhatToShow(whatToShow)
{}
DOMNodeFilter::FilterAction DOMPrintFilter::
acceptNode(const DOMNode* node) const
{
//
// The DOMLSSerializer shall call getWhatToShow() before calling
// acceptNode(), to show nodes which are supposed to be
// shown to this filter.
//
// REVISIT: In case the DOMLSSerializer does not follow the protocol,
// Shall the filter honour, or NOT, what it claims
// it is interested in ?
//
// The DOMLS specs does not specify that acceptNode() shall do
// this way, or not, so it is up the implementation,
// to skip the code below for the sake of performance ...
//
if ((getWhatToShow() & (1 << (node->getNodeType() - 1))) == 0)
return DOMNodeFilter::FILTER_ACCEPT;
switch (node->getNodeType())
{
case DOMNode::ELEMENT_NODE:
{
// for element whose name is "person", skip it
if (XMLString::compareString(node->getNodeName(), element_person)==0)
return DOMNodeFilter::FILTER_SKIP;
// for element whose name is "line", reject it
if (XMLString::compareString(node->getNodeName(), element_link)==0)
return DOMNodeFilter::FILTER_REJECT;
// for rest, accept it
return DOMNodeFilter::FILTER_ACCEPT;
break;
}
case DOMNode::COMMENT_NODE:
{
// the WhatToShow will make this no effect
return DOMNodeFilter::FILTER_REJECT;
break;
}
case DOMNode::TEXT_NODE:
{
// the WhatToShow will make this no effect
return DOMNodeFilter::FILTER_REJECT;
break;
}
case DOMNode::DOCUMENT_TYPE_NODE:
{
// even we say we are going to process document type,
// we are not able be to see this node since
// DOMLSSerializerImpl (a XercesC's default implementation
// of DOMLSSerializer) will not pass DocumentType node to
// this filter.
//
return DOMNodeFilter::FILTER_REJECT; // no effect
break;
}
case DOMNode::DOCUMENT_NODE:
{
// same as DOCUMENT_NODE
return DOMNodeFilter::FILTER_REJECT; // no effect
break;
}
default :
{
return DOMNodeFilter::FILTER_ACCEPT;
break;
}
}
return DOMNodeFilter::FILTER_ACCEPT;
}
Solution 2
LibXML++ appears to be the best one for C++. Feature-wise it is very complete, including XPath, charset conversions (by Glibmm) and everything that you'd expect in an XML library. It uses traditional DOM and SAX APIs, which counts as a pro or a con depending on whom you ask from. One possible issue is that the dependencies of the library are extremely heavy (due to the use of Glibmm). Still, it appears to be the only decent XML library for C++.
http://libxmlplusplus.sourceforge.net/docs/manual/html/index.html
TinyXML does not parse XML according to the specification, so I would recommend against it, even though it works for simple documents.
Admin
Updated on June 14, 2022Comments
-
Admin about 2 years
I'm searching for a tutorial to load a XML file, read it, change it and finally save it with C++. I'm using Linux Ubuntu and tried to use Xerces. With Google and much time, I could only load an XML File:
#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> #include <iostream> using namespace std; using namespace xercesc; int main (int argc, char* args[]) { try { XMLPlatformUtils::Initialize(); } catch (const XMLException& toCatch) { char* message = XMLString::transcode(toCatch.getMessage()); cout << "Error during initialization! :\n" << message << "\n"; XMLString::release(&message); return 1; } XercesDOMParser* parser = new XercesDOMParser(); parser->setValidationScheme(XercesDOMParser::Val_Always); parser->setDoNamespaces(true); // optional ErrorHandler* errHandler = (ErrorHandler*) new HandlerBase(); parser->setErrorHandler(errHandler); const char* xmlFile = "demo.xml"; try { parser->parse(xmlFile); } catch (const XMLException& toCatch) { char* message = XMLString::transcode(toCatch.getMessage()); cout << "Exception message is: \n" << message << "\n"; XMLString::release(&message); return -1; } catch (const DOMException& toCatch) { char* message = XMLString::transcode(toCatch.msg); cout << "Exception message is: \n" << message << "\n"; XMLString::release(&message); return -1; } catch (...) { cout << "Unexpected Exception \n" ; return -1; } DOMNode* docRootNode; // DOMNode* aNode; DOMDocument* doc; doc = parser->getDocument(); docRootNode = doc->getDocumentElement(); cout << docRootNode->getAttributes() << endl; //returns Hex delete parser; delete errHandler; return 0; }
How do I can read an manipulate the XML file and finally save it? Is there alternative libraries? (I tried tinyxml but the files returns errors, when I want to compile it)