arabica/include/SAX/wrappers/saxlibxml2.hpp

860 lines
34 KiB
C++
Raw Normal View History

2003-09-11 12:26:53 +02:00
#ifndef ARABICA_SAX_LIBXML2_H
#define ARABICA_SAX_LIBXML2_H
2002-06-21 13:16:28 +02:00
////////////////////////////////////////////////////////////////
// A SAX2 Wrapper for libxml2
//
// $Id$
////////////////////////////////////////////////////////////////
2007-09-05 00:55:47 +02:00
#include <SAX/ArabicaConfig.hpp>
#include <SAX/XMLReader.hpp>
#include <SAX/SAXParseException.hpp>
#include <SAX/InputSource.hpp>
#include <SAX/SAXNotSupportedException.hpp>
#include <SAX/SAXNotRecognizedException.hpp>
2002-06-21 13:16:28 +02:00
#include <libxml/parser.h>
#include <string>
#include <cstdarg>
#include <typeinfo>
2007-09-05 00:55:47 +02:00
#include <SAX/helpers/FeatureNames.hpp>
#include <SAX/helpers/PropertyNames.hpp>
#include <SAX/helpers/NamespaceSupport.hpp>
#include <SAX/helpers/AttributeDefaults.hpp>
#include <SAX/helpers/AttributeTypes.hpp>
#include <SAX/helpers/InputSourceResolver.hpp>
#include <SAX/helpers/AttributesImpl.hpp>
#include <Arabica/getparam.hpp>
2002-06-21 13:16:28 +02:00
2007-09-05 11:49:18 +02:00
namespace Arabica
{
2002-06-21 13:16:28 +02:00
namespace SAX
{
////////////////////////////////////////////////////////////////////////////
// the callback functions for libxml
namespace libxml2_wrapper_impl_tiddle
{
extern "C"
{
class libxml2_base
{
2005-08-07 22:16:02 +02:00
protected:
virtual ~libxml2_base() { }
2002-06-21 13:16:28 +02:00
private:
virtual void SAXstartDocument() = 0;
virtual void SAXendDocument() = 0;
virtual void SAXlocator(xmlSAXLocatorPtr locator) = 0;
virtual void SAXcharacters(const xmlChar* ch, int len) = 0;
virtual void SAXignorableWhitespace(const xmlChar* ch, int len) = 0;
virtual void SAXwarning(const std::string& warning) = 0;
virtual void SAXerror(const std::string& error) = 0;
virtual void SAXfatalError(const std::string& fatal) = 0;
virtual void SAXprocessingInstruction(const xmlChar* target, const xmlChar* data) = 0;
virtual void SAXcomment(const xmlChar* comment) = 0;
2002-06-21 13:16:28 +02:00
virtual void SAXstartElement(const xmlChar* name, const xmlChar** attrs) = 0;
virtual void SAXendElement(const xmlChar* name) = 0;
virtual void SAXnotationDecl(const xmlChar *name, const xmlChar *publicId, const xmlChar *systemId) = 0;
virtual void SAXunparsedEntityDecl(const xmlChar *name, const xmlChar *publicId, const xmlChar *systemId, const xmlChar *notationName) = 0;
virtual void SAXelementDecl(const xmlChar* name, int type, xmlElementContentPtr content) = 0;
virtual void SAXattributeDecl(const xmlChar *elem, const xmlChar *fullname, int type, int def, const xmlChar *defaultValue, xmlEnumerationPtr tree) = 0;
virtual void SAXentityDecl(const xmlChar *name, int type, const xmlChar *publicId, const xmlChar *systemId, xmlChar *content) = 0;
virtual xmlParserInputPtr SAXresolveEntity(const xmlChar* publicId, const xmlChar* systemId) = 0;
friend void lwit_startDocument(void* user_data);
friend void lwit_endDocument(void* user_data);
friend void lwit_characters(void *user_data, const xmlChar* ch, int len);
friend void lwit_ignorableWhitespace(void *user_data, const xmlChar* ch, int len);
friend void lwit_locator(void* user_data, xmlSAXLocatorPtr locator);
friend void lwit_warning(void *user_data, const char* fmt, ...);
friend void lwit_error(void* user_data, const char* fmt, ...);
friend void lwit_fatalError(void* user_data, const char* fmt, ...);
friend void lwit_processingInstruction(void *user_data, const xmlChar* target, const xmlChar* data);
friend void lwit_comment(void *user_data, const xmlChar* comment);
2002-06-21 13:16:28 +02:00
friend void lwit_startElement(void *user_data, const xmlChar* name, const xmlChar** attrs);
friend void lwit_endElement(void* user_data, const xmlChar* name);
friend void lwit_notationDecl(void* user_data, const xmlChar *name, const xmlChar *publicId, const xmlChar *systemId);
friend void lwit_unparsedEntityDecl(void* user_data, const xmlChar *name, const xmlChar *publicId, const xmlChar *systemId, const xmlChar *notationName);
friend void lwit_elementDecl(void* user_data, const xmlChar *name, int type, xmlElementContentPtr content);
friend void lwit_attributeDecl(void* user_data, const xmlChar *elem, const xmlChar *fullname, int type, int def, const xmlChar *defaultValue, xmlEnumerationPtr tree);
friend void lwit_entityDecl(void* user_data, const xmlChar *name, int type, const xmlChar *publicId, const xmlChar *systemId, xmlChar *content);
friend xmlParserInputPtr lwit_resolveEntity(void* user_data, const xmlChar* publicId, const xmlChar* systemId);
}; // class libxml2_base
void lwit_startDocument(void* user_data);
void lwit_endDocument(void* user_data);
void lwit_startElement(void *user_data, const xmlChar* name, const xmlChar** attrs);
void lwit_endElement(void *user_data, const xmlChar* name);
void lwit_characters(void* user_data, const xmlChar* ch, int len);
void lwit_ignorableWhitespace(void *user_data, const xmlChar* ch, int len);
void lwit_processingInstruction(void *user_data, const xmlChar* target, const xmlChar* data);
void lwit_comment(void *user_data, const xmlChar* comment);
2002-06-21 13:16:28 +02:00
void lwit_warning(void *user_data, const char* fmt, ...);
void lwit_error(void* user_data, const char* fmt, ...);
void lwit_fatalError(void* user_data, const char* fmt, ...);
void lwit_locator(void* user_data, xmlSAXLocatorPtr locator);
void lwit_notationDecl(void* user_data, const xmlChar *name, const xmlChar *publicId, const xmlChar *systemId);
void lwit_unparsedEntityDecl(void* user_data,
const xmlChar *name, const xmlChar *publicId,
const xmlChar *systemId, const xmlChar *notationName);
void lwit_elementDecl(void* user_date, const xmlChar *name, int type, xmlElementContentPtr content);
void lwit_attributeDecl(void *user_data, const xmlChar *elem, const xmlChar *fullname, int type, int def, const xmlChar *defaultValue, xmlEnumerationPtr tree);
void lwit_entityDecl(void* user_data, const xmlChar *name, int type, const xmlChar *publicId, const xmlChar *systemId, xmlChar *content);
void lwit_setFeature(xmlParserCtxtPtr context, const char* name, bool value);
bool lwit_getFeature(xmlParserCtxtPtr context, const char* name);
xmlParserInputPtr lwit_resolveEntity(void* user_data, const xmlChar* publicId, const xmlChar* systemId);
xmlSAXHandler* lwit_SaxHandler();
} // extern "C"
} // namespace libxml2_wrapper_impl_tiddle
template<class string_type,
class T0 = Arabica::nil_t,
class T1 = Arabica::nil_t>
2007-09-06 11:04:01 +02:00
class libxml2_wrapper : public XMLReaderInterface<string_type, T0, T1>,
public Locator<string_type, typename XMLReaderInterface<string_type, T0, T1>::string_adaptor>,
2002-06-21 13:16:28 +02:00
protected libxml2_wrapper_impl_tiddle::libxml2_base
{
public:
2007-09-06 11:04:01 +02:00
typedef XMLReaderInterface<string_type, T0, T1> XMLReaderT;
typedef typename XMLReaderT::string_adaptor string_adaptor;
typedef SAX::EntityResolver<string_type, string_adaptor> entityResolverT;
typedef SAX::DTDHandler<string_type, string_adaptor> dtdHandlerT;
typedef SAX::ContentHandler<string_type, string_adaptor> contentHandlerT;
typedef SAX::Attributes<string_type, string_adaptor> attributesT;
typedef SAX::AttributeType<string_type, string_adaptor> attributeTypeT;
2007-09-06 11:04:01 +02:00
typedef SAX::DeclHandler<string_type, string_adaptor> declHandlerT;
typedef SAX::LexicalHandler<string_type, string_adaptor> lexicalHandlerT;
typedef SAX::InputSource<string_type, string_adaptor> inputSourceT;
typedef SAX::Locator<string_type, string_adaptor> locatorT;
typedef SAX::NamespaceSupport<string_type, string_adaptor> namespaceSupportT;
typedef SAX::ErrorHandler<string_type, string_adaptor> errorHandlerT;
typedef SAX::SAXParseException<string_type, string_adaptor> SAXParseExceptionT;
2005-08-01 12:21:44 +02:00
typedef typename XMLReaderT::PropertyBase PropertyBaseT;
typedef typename XMLReaderT::template Property<lexicalHandlerT*> getLexicalHandlerT;
typedef typename XMLReaderT::template Property<lexicalHandlerT&> setLexicalHandlerT;
typedef typename XMLReaderT::template Property<declHandlerT*> getDeclHandlerT;
typedef typename XMLReaderT::template Property<declHandlerT&> setDeclHandlerT;
2002-06-21 13:16:28 +02:00
libxml2_wrapper();
~libxml2_wrapper();
////////////////////////////////////////////////
// configuration
2007-09-06 11:04:01 +02:00
virtual bool getFeature(const string_type& name) const;
virtual void setFeature(const string_type& name, bool value);
2002-06-21 13:16:28 +02:00
////////////////////////////////////////////////
// Event Handlers
virtual void setEntityResolver(entityResolverT& resolver) { entityResolver_ = &resolver; }
virtual entityResolverT* getEntityResolver() const { return entityResolver_; }
virtual void setDTDHandler(dtdHandlerT& handler) { dtdHandler_ = &handler; }
virtual dtdHandlerT* getDTDHandler() const { return dtdHandler_; }
virtual void setContentHandler(contentHandlerT& handler) { contentHandler_ = &handler; }
virtual contentHandlerT* getContentHandler() const { return contentHandler_; }
virtual void setErrorHandler(errorHandlerT& handler) { errorHandler_ = &handler; }
virtual errorHandlerT* getErrorHandler() const { return errorHandler_; }
virtual void setDeclHandler(declHandlerT& handler) { declHandler_ = &handler; }
virtual declHandlerT* getDeclHandler() const { return declHandler_; }
virtual void setLexicalHandler(lexicalHandlerT& handler) { lexicalHandler_ = &handler; }
virtual lexicalHandlerT* getLexicalHandler() const { return lexicalHandler_; }
2002-06-21 13:16:28 +02:00
////////////////////////////////////////////////
// parsing
virtual void parse(inputSourceT& source);
2002-06-21 13:16:28 +02:00
protected:
////////////////////////////////////////////////
// properties
2007-09-06 11:04:01 +02:00
virtual std::auto_ptr<PropertyBaseT> doGetProperty(const string_type& name);
virtual void doSetProperty(const string_type& name, std::auto_ptr<PropertyBaseT> value);
2002-06-21 13:16:28 +02:00
public:
2007-09-06 11:04:01 +02:00
virtual string_type getPublicId() const;
virtual string_type getSystemId() const;
2002-06-21 13:16:28 +02:00
virtual int getLineNumber() const;
virtual int getColumnNumber() const;
private:
virtual void SAXstartDocument();
virtual void SAXendDocument();
virtual void SAXlocator(xmlSAXLocatorPtr locator) { locator_ = locator; }
virtual void SAXcharacters(const xmlChar* ch, int len);
virtual void SAXignorableWhitespace(const xmlChar* ch, int len);
virtual void SAXwarning(const std::string& warning);
virtual void SAXerror(const std::string& error);
virtual void SAXfatalError(const std::string& fatal);
virtual void SAXprocessingInstruction(const xmlChar* target, const xmlChar* data);
virtual void SAXcomment(const xmlChar* comment);
2002-06-21 13:16:28 +02:00
virtual void SAXstartElement(const xmlChar* name, const xmlChar** attrs);
virtual void SAXstartElementNoNS(const xmlChar* name, const xmlChar** attrs);
virtual void SAXendElement(const xmlChar* name);
virtual void SAXendElementNoNS(const xmlChar* name);
virtual void SAXnotationDecl(const xmlChar *name, const xmlChar *publicId, const xmlChar *systemId);
virtual void SAXunparsedEntityDecl(const xmlChar *name, const xmlChar *publicId, const xmlChar *systemId, const xmlChar *notationName);
virtual void SAXelementDecl(const xmlChar* name, int type, xmlElementContentPtr content);
void convertXML_Content(std::ostream& os, int type, xmlElementContentPtr model, bool isChild) const;
virtual void SAXattributeDecl(const xmlChar *elem, const xmlChar *fullname, int type, int def, const xmlChar *defaultValue, xmlEnumerationPtr tree);
2007-09-06 11:04:01 +02:00
string_type stringAttrEnum(xmlEnumerationPtr tree, bool leadingSpace) const;
2002-06-21 13:16:28 +02:00
virtual void SAXentityDecl(const xmlChar *name, int type, const xmlChar *publicId, const xmlChar *systemId, xmlChar *content);
virtual xmlParserInputPtr SAXresolveEntity(const xmlChar* publicId, const xmlChar* systemId);
2007-09-06 11:04:01 +02:00
typename NamespaceSupport<string_type, string_adaptor>::Parts processName(const string_type& qName, bool isAttribute);
2002-06-21 13:16:28 +02:00
void reportError(const std::string& message, bool fatal = false);
2007-09-06 11:04:01 +02:00
void checkNotParsing(const string_type& type, const string_type& name) const;
2002-06-21 13:16:28 +02:00
private:
// member variables
entityResolverT* entityResolver_;
dtdHandlerT* dtdHandler_;
contentHandlerT* contentHandler_;
errorHandlerT* errorHandler_;
2002-06-21 13:16:28 +02:00
namespaceSupportT nsSupport_;
declHandlerT* declHandler_;
lexicalHandlerT* lexicalHandler_;
2002-06-21 13:16:28 +02:00
xmlParserCtxtPtr context_;
xmlSAXLocatorPtr locator_;
bool parsing_;
bool namespaces_;
bool prefixes_;
2007-09-06 11:04:01 +02:00
string_type emptyString_;
const FeatureNames<string_type, string_adaptor> features_;
const PropertyNames<string_type, string_adaptor> properties_;
const NamespaceConstants<string_type, string_adaptor> nsc_;
const AttributeDefaults<string_type, string_adaptor> attrDefaults_;
const AttributeTypes<string_type, string_adaptor> attrTypes_;
2002-06-21 13:16:28 +02:00
}; // class libxml2_wrapper
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
libxml2_wrapper<string_type, T0, T1>::libxml2_wrapper() :
2002-06-21 13:16:28 +02:00
entityResolver_(0),
dtdHandler_(0),
contentHandler_(0),
errorHandler_(0),
declHandler_(0),
2002-06-21 13:16:28 +02:00
locator_(0),
parsing_(false),
namespaces_(true),
prefixes_(true)
{
2005-04-08 18:02:31 +02:00
context_ = xmlCreatePushParserCtxt(libxml2_wrapper_impl_tiddle::lwit_SaxHandler(),
reinterpret_cast<void*>(static_cast<libxml2_wrapper_impl_tiddle::libxml2_base*>(this)),
0,
0,
0);
xmlCtxtUseOptions(context_, XML_PARSE_DTDLOAD + XML_PARSE_DTDVALID + XML_PARSE_NOBLANKS);
2002-06-21 13:16:28 +02:00
} // libxml2_wrapper
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
libxml2_wrapper<string_type, T0, T1>::~libxml2_wrapper()
2002-06-21 13:16:28 +02:00
{
xmlFreeParserCtxt(context_);
} // ~libxml2_wrapper
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
bool libxml2_wrapper<string_type, T0, T1>::getFeature(const string_type& name) const
2002-06-21 13:16:28 +02:00
{
if(name == features_.namespaces)
return namespaces_;
if(name == features_.namespace_prefixes)
return prefixes_;
if(name == features_.validation)
return libxml2_wrapper_impl_tiddle::lwit_getFeature(context_, "validate");
if(name == features_.external_general)
return libxml2_wrapper_impl_tiddle::lwit_getFeature(context_, "fetch external entities");
if(name == features_.external_parameter)
{
2007-09-06 11:04:01 +02:00
throw SAX::SAXNotSupportedException(std::string("Feature not supported ") + string_adaptor::asStdString(name));
2002-06-21 13:16:28 +02:00
}
else
{
2007-09-06 11:04:01 +02:00
throw SAX::SAXNotRecognizedException(std::string("Feature not recognized ") + string_adaptor::asStdString(name));
2002-06-21 13:16:28 +02:00
}
} // getFeature
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::setFeature(const string_type& name, bool value)
2002-06-21 13:16:28 +02:00
{
if(name == features_.namespaces)
{
2007-09-06 11:04:01 +02:00
checkNotParsing(string_adaptor::construct_from_utf8("feature"), name);
2002-06-21 13:16:28 +02:00
namespaces_ = value;
if(!namespaces_ && !prefixes_)
prefixes_ = true;
return;
}
if(name == features_.namespace_prefixes)
{
2007-09-06 11:04:01 +02:00
checkNotParsing(string_adaptor::construct_from_utf8("feature"), name);
2002-06-21 13:16:28 +02:00
prefixes_ = value;
if(prefixes_ && !namespaces_)
namespaces_ = true;
return;
}
if(name == features_.validation)
{
libxml2_wrapper_impl_tiddle::lwit_setFeature(context_, "validate", value);
return;
} // if ...
if(name == features_.external_general)
{
libxml2_wrapper_impl_tiddle::lwit_setFeature(context_, "fetch external entities", value);
return;
} // if ...
if(name == features_.external_parameter)
{
std::ostringstream os;
2007-09-06 11:04:01 +02:00
os << "Feature not supported " << string_adaptor::asStdString(name);
2002-06-21 13:16:28 +02:00
throw SAX::SAXNotSupportedException(os.str());
}
else
{
std::ostringstream os;
2007-09-06 11:04:01 +02:00
os << "Feature not recognized " << string_adaptor::asStdString(name);
2002-06-21 13:16:28 +02:00
throw SAX::SAXNotRecognizedException(os.str());
}
} // setFeature
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
2003-09-15 18:04:37 +02:00
#ifndef ARABICA_VS6_WORKAROUND
2007-09-06 11:04:01 +02:00
std::auto_ptr<typename libxml2_wrapper<string_type, T0, T1>::PropertyBaseT> libxml2_wrapper<string_type, T0, T1>::doGetProperty(const string_type& name)
2003-09-15 18:04:37 +02:00
#else
2007-09-06 11:04:01 +02:00
std::auto_ptr<libxml2_wrapper<string_type, T0, T1>::PropertyBaseT> libxml2_wrapper<string_type, T0, T1>::doGetProperty(const string_type& name)
2003-09-15 18:04:37 +02:00
#endif
2002-06-21 13:16:28 +02:00
{
if(name == properties_.declHandler)
{
2005-08-01 12:21:44 +02:00
getDeclHandlerT* prop = new getDeclHandlerT(declHandler_);
return std::auto_ptr<PropertyBaseT>(prop);
2002-06-21 13:16:28 +02:00
}
2005-08-01 12:21:44 +02:00
if(name == properties_.lexicalHandler)
{
getLexicalHandlerT* prop = new getLexicalHandlerT(lexicalHandler_);
return std::auto_ptr<PropertyBaseT>(prop);
}
2002-06-21 13:16:28 +02:00
2007-09-06 11:04:01 +02:00
throw SAX::SAXNotRecognizedException(std::string("Property not recognized ") + string_adaptor::asStdString(name));
2002-06-21 13:16:28 +02:00
} // doGetProperty
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::doSetProperty(const string_type& name, std::auto_ptr<PropertyBaseT> value)
2002-06-21 13:16:28 +02:00
{
if(name == properties_.declHandler)
{
2005-08-01 12:21:44 +02:00
setDeclHandlerT* prop = dynamic_cast<setDeclHandlerT*>(value.get());
2002-06-21 13:16:28 +02:00
if(!prop)
2005-08-01 12:21:44 +02:00
throw std::bad_cast();
2002-06-21 13:16:28 +02:00
declHandler_ = &(prop->get());
2005-08-01 12:21:44 +02:00
}
if(name == properties_.lexicalHandler)
{
setLexicalHandlerT* prop = dynamic_cast<setLexicalHandlerT*>(value.get());
if(!prop)
throw std::bad_cast();
lexicalHandler_ = &(prop->get());
}
2002-06-21 13:16:28 +02:00
2007-09-06 11:04:01 +02:00
throw SAX::SAXNotRecognizedException(std::string("Property not recognized ") + string_adaptor::asStdString(name));
2002-06-21 13:16:28 +02:00
} // doSetProperty
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
typename SAX::NamespaceSupport<string_type, typename libxml2_wrapper<string_type, T0, T1>::string_adaptor>::Parts libxml2_wrapper<string_type, T0, T1>::processName(const string_type& qName, bool isAttribute)
2002-06-21 13:16:28 +02:00
{
2007-09-06 11:04:01 +02:00
typename NamespaceSupport<string_type, string_adaptor>::Parts p =
nsSupport_.processName(qName, isAttribute);
2007-09-06 11:04:01 +02:00
if(string_adaptor::empty(p.URI) && !string_adaptor::empty(p.prefix))
reportError(std::string("Undeclared prefix ") + string_adaptor::asStdString(qName));
2002-06-21 13:16:28 +02:00
return p;
} // processName
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::reportError(const std::string& message, bool fatal)
2002-06-21 13:16:28 +02:00
{
if(!errorHandler_)
return;
SAXParseExceptionT e(message, *this);
2002-06-21 13:16:28 +02:00
if(fatal)
errorHandler_->fatalError(e);
else
errorHandler_->error(e);
} // reportError
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::checkNotParsing(const string_type& type, const string_type& name) const
2002-06-21 13:16:28 +02:00
{
if(parsing_)
{
std::ostringstream os;
2007-09-06 11:04:01 +02:00
os << "Can't change " << string_adaptor::asStdString(type) << " " << string_adaptor::asStdString(name) << " while parsing";
2002-06-21 13:16:28 +02:00
throw SAX::SAXNotSupportedException(os.str());
} // if(parsing_)
} // checkNotParsing
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
string_type libxml2_wrapper<string_type, T0, T1>::getPublicId() const
2002-06-21 13:16:28 +02:00
{
if(locator_)
2007-09-06 11:04:01 +02:00
return string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(locator_->getPublicId(context_)));
return string_type();
2002-06-21 13:16:28 +02:00
} // getPublicId
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
string_type libxml2_wrapper<string_type, T0, T1>::getSystemId() const
2002-06-21 13:16:28 +02:00
{
if(locator_)
2007-09-06 11:04:01 +02:00
return string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(locator_->getSystemId(context_)));
return string_type();
2002-06-21 13:16:28 +02:00
} // getSystemId
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
int libxml2_wrapper<string_type, T0, T1>::getLineNumber() const
2002-06-21 13:16:28 +02:00
{
if(locator_)
return locator_->getLineNumber(context_);
return -1;
} // getLineNumber
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
int libxml2_wrapper<string_type, T0, T1>::getColumnNumber() const
2002-06-21 13:16:28 +02:00
{
if(locator_)
return locator_->getColumnNumber(context_);
return -1;
} // getColumnNumber
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::parse(inputSourceT& source)
2002-06-21 13:16:28 +02:00
{
if(contentHandler_)
contentHandler_->setDocumentLocator(*this);
2007-09-06 11:04:01 +02:00
InputSourceResolver is(source, string_adaptor());
2002-06-21 13:16:28 +02:00
if(is.resolve() == 0)
return;
parsing_ = true;
while(!is.resolve()->eof())
{
2005-12-02 18:04:56 +01:00
char buffer[4096];
2002-06-21 13:16:28 +02:00
is.resolve()->read(buffer, sizeof(buffer));
xmlParseChunk(context_, buffer, is.resolve()->gcount(), is.resolve()->eof());
} // while(!in.eof())
2007-08-07 23:43:36 +02:00
xmlCtxtResetPush(context_, 0, 0, 0, 0);
2002-06-21 13:16:28 +02:00
parsing_ = false;
} // parse
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXstartDocument()
2002-06-21 13:16:28 +02:00
{
if(contentHandler_)
contentHandler_->startDocument();
} // SAXstartDocument
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXendDocument()
2002-06-21 13:16:28 +02:00
{
if(contentHandler_)
contentHandler_->endDocument();
} // SAXendDocument
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXcharacters(const xmlChar* ch, int len)
2002-06-21 13:16:28 +02:00
{
if(contentHandler_)
2007-09-06 11:04:01 +02:00
contentHandler_->characters(string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(ch), len));
2002-06-21 13:16:28 +02:00
} // SAXcharacters
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXignorableWhitespace(const xmlChar* ch, int len)
2002-06-21 13:16:28 +02:00
{
if(contentHandler_)
2007-09-06 11:04:01 +02:00
contentHandler_->ignorableWhitespace(string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(ch), len));
2002-06-21 13:16:28 +02:00
} // SAXignorableWhitespace
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXwarning(const std::string& warning)
2002-06-21 13:16:28 +02:00
{
if(errorHandler_)
errorHandler_->warning(SAXParseExceptionT(warning, *this));
2002-06-21 13:16:28 +02:00
} // warning
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXerror(const std::string& error)
2002-06-21 13:16:28 +02:00
{
if(errorHandler_)
errorHandler_->error(SAXParseExceptionT(error, *this));
2002-06-21 13:16:28 +02:00
} // error
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXfatalError(const std::string& fatal)
2002-06-21 13:16:28 +02:00
{
if(errorHandler_)
errorHandler_->fatalError(SAXParseExceptionT(fatal, *this));
2002-06-21 13:16:28 +02:00
} // fatal
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXprocessingInstruction(const xmlChar* target, const xmlChar* data)
2002-06-21 13:16:28 +02:00
{
if(contentHandler_)
2007-09-06 11:04:01 +02:00
contentHandler_->processingInstruction(string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(target)),
string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(data)));
2002-06-21 13:16:28 +02:00
} // SAXprocessingInstruction
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXcomment(const xmlChar* comment)
{
if(lexicalHandler_)
2007-09-06 11:04:01 +02:00
lexicalHandler_->comment(string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(comment)));
} // SAXcomment
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXstartElement(const xmlChar* qName, const xmlChar** atts)
2002-06-21 13:16:28 +02:00
{
if(!contentHandler_)
return;
if(!namespaces_)
{
SAXstartElementNoNS(qName, atts);
return;
} // if(!namespaces)
// OK we're doing Namespaces
nsSupport_.pushContext();
2007-09-06 11:04:01 +02:00
SAX::AttributesImpl<string_type, string_adaptor> attributes;
2002-06-21 13:16:28 +02:00
// take a first pass and copy all the attributes, noting any declarations
if(atts && *atts != 0)
{
2005-08-02 12:59:34 +02:00
const xmlChar** a1 = atts;
while(*a1 != 0)
2002-06-21 13:16:28 +02:00
{
2007-09-06 11:04:01 +02:00
string_type attQName = string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(*a1++));
string_type value = string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(*a1++));
2002-06-21 13:16:28 +02:00
// declaration?
2007-09-06 11:04:01 +02:00
if(string_adaptor::find(attQName, nsc_.xmlns) == 0)
2002-06-21 13:16:28 +02:00
{
2007-09-06 11:04:01 +02:00
string_type prefix;
typename string_adaptor::size_type n = string_adaptor::find(attQName, nsc_.colon);
if(n != string_adaptor::npos())
prefix = string_adaptor::construct(string_adaptor::begin(attQName) + n + 1, string_adaptor::end(attQName));
2002-06-21 13:16:28 +02:00
if(!nsSupport_.declarePrefix(prefix, value))
2007-09-06 11:04:01 +02:00
reportError(std::string("Illegal Namespace prefix ") + string_adaptor::asStdString(prefix));
2002-06-21 13:16:28 +02:00
contentHandler_->startPrefixMapping(prefix, value);
if(prefixes_)
attributes.addAttribute(emptyString_,
emptyString_,
attQName,
attributeTypeT::CDATA,
2002-06-21 13:16:28 +02:00
value);
}
2005-08-02 12:59:34 +02:00
} // while
while(*atts != 0)
{
2007-09-06 11:04:01 +02:00
string_type attQName = string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(*atts++));
string_type value = string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(*atts++));
2005-08-02 12:59:34 +02:00
// declaration?
2007-09-06 11:04:01 +02:00
if(string_adaptor::find(attQName, nsc_.xmlns) != 0)
2002-06-21 13:16:28 +02:00
{
2007-09-06 11:04:01 +02:00
typename NamespaceSupport<string_type, string_adaptor>::Parts attName = processName(attQName, true);
attributes.addAttribute(attName.URI,
attName.localName,
attName.rawName,
attributeTypeT::CDATA,
value);
2002-06-21 13:16:28 +02:00
}
} // while ...
} // if ...
// at last! report the event
2007-09-06 11:04:01 +02:00
typename NamespaceSupport<string_type, string_adaptor>::Parts name = processName(string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(qName)), false);
2002-06-21 13:16:28 +02:00
contentHandler_->startElement(name.URI, name.localName, name.rawName, attributes);
} // SAXstartElement
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXstartElementNoNS(const xmlChar* qName, const xmlChar** atts)
2002-06-21 13:16:28 +02:00
{
2007-09-06 11:04:01 +02:00
SAX::AttributesImpl<string_type, string_adaptor> attributes;
2002-06-21 13:16:28 +02:00
if(atts && *atts != 0)
{
while(*atts != 0)
{
2007-09-06 11:04:01 +02:00
string_type attQName = string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(*atts++));
string_type value = string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(*atts++));
2002-06-21 13:16:28 +02:00
attributes.addAttribute(emptyString_,
emptyString_,
attQName,
attributeTypeT::CDATA,
value);
2002-06-21 13:16:28 +02:00
} // while ..
} // if ...
2007-09-06 11:04:01 +02:00
contentHandler_->startElement(emptyString_, emptyString_, string_adaptor::construct_from_utf8((reinterpret_cast<const char*>(qName))), attributes);
2002-06-21 13:16:28 +02:00
} // SAXstartElementNoNS
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXendElement(const xmlChar* qName)
2002-06-21 13:16:28 +02:00
{
if(!contentHandler_)
return;
if(!namespaces_)
{
SAXendElementNoNS(qName);
return;
} // if(!namespaces_)
2007-09-06 11:04:01 +02:00
typename NamespaceSupport<string_type, string_adaptor>::Parts name = processName(string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(qName)), false);
2002-06-21 13:16:28 +02:00
contentHandler_->endElement(name.URI, name.localName, name.rawName);
2007-09-06 11:04:01 +02:00
typename NamespaceSupport<string_type, string_adaptor>::stringListT prefixes = nsSupport_.getDeclaredPrefixes();
for(size_t i = 0, end = prefixes.size(); i < end; ++i)
2002-06-21 13:16:28 +02:00
contentHandler_->endPrefixMapping(prefixes[i]);
nsSupport_.popContext();
} // SAXendElement
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXendElementNoNS(const xmlChar* qName)
2002-06-21 13:16:28 +02:00
{
if(contentHandler_)
2007-09-06 11:04:01 +02:00
contentHandler_->endElement(emptyString_, emptyString_, string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(qName)));
2002-06-21 13:16:28 +02:00
} // SAXendElementNoNS
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXnotationDecl(const xmlChar *name, const xmlChar *publicId, const xmlChar *systemId)
2002-06-21 13:16:28 +02:00
{
if(dtdHandler_)
2007-09-06 11:04:01 +02:00
dtdHandler_->notationDecl(string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(name)),
string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(publicId)),
string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(systemId)));
2002-06-21 13:16:28 +02:00
} // SAXnotationDecl
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXunparsedEntityDecl(const xmlChar *name, const xmlChar *publicId, const xmlChar *systemId, const xmlChar *notationName)
2002-06-21 13:16:28 +02:00
{
if(dtdHandler_)
2007-09-06 11:04:01 +02:00
dtdHandler_->unparsedEntityDecl(string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(name)),
string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(publicId)),
string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(systemId)),
string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(notationName)));
2002-06-21 13:16:28 +02:00
} // SAXunparsedEntityDecl
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXelementDecl(const xmlChar* name, int type, xmlElementContentPtr content)
2002-06-21 13:16:28 +02:00
{
if(!declHandler_)
return;
std::ostringstream os;
convertXML_Content(os, type, content, false);
2007-09-06 11:04:01 +02:00
declHandler_->elementDecl(string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(name)), string_adaptor::construct_from_utf8(os.str().c_str()));
2002-06-21 13:16:28 +02:00
} // elementDeclaration
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::convertXML_Content(std::ostream& os, int type, xmlElementContentPtr model, bool isChild) const
2002-06-21 13:16:28 +02:00
{
char concatenator = ' ';
switch(type)
{
case XML_ELEMENT_TYPE_EMPTY:
os << "EMPTY";
break;
case XML_ELEMENT_TYPE_ANY:
os << "ANY";
return;
case XML_ELEMENT_TYPE_MIXED:
if(model->c1 == 0)
os << "(#PCDATA)";
else
os << "(#PCDATA";
concatenator = '|';
break;
case XML_ELEMENT_TYPE_ELEMENT:
break;
} // switch
switch(model->type)
{
case XML_ELEMENT_CONTENT_ELEMENT:
if(!isChild)
os << '(' << model->name << ')';
else
os << model->name;
break;
case XML_ELEMENT_CONTENT_SEQ:
concatenator = ',';
break;
case XML_ELEMENT_CONTENT_OR:
concatenator = '|';
break;
case XML_ELEMENT_CONTENT_PCDATA:
break;
2002-06-21 13:16:28 +02:00
} // switch
// do children here
if(model->c1 != 0)
{
if(!isChild)
os << '(';
convertXML_Content(os, XML_ELEMENT_TYPE_ELEMENT, model->c1, true);
if(model->c2 != 0)
{
os << concatenator;
convertXML_Content(os, XML_ELEMENT_TYPE_ELEMENT, model->c2, true);
} // if ...
if(!isChild)
os << ')';
} // if ...
switch(model->ocur)
{
case XML_ELEMENT_CONTENT_ONCE:
break;
case XML_ELEMENT_CONTENT_OPT:
os << "?";
break;
case XML_ELEMENT_CONTENT_MULT:
os << "*";
break;
case XML_ELEMENT_CONTENT_PLUS:
os << "+";
break;
} // switch
} // convertXML_Content
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXattributeDecl(const xmlChar *elem, const xmlChar *fullname, int type, int def, const xmlChar *defaultValue, xmlEnumerationPtr tree)
2002-06-21 13:16:28 +02:00
{
if(!declHandler_)
return;
2007-09-06 11:04:01 +02:00
const string_type* defType = &attrDefaults_.implied;
2002-06-21 13:16:28 +02:00
if(def)
defType = (defaultValue) ? &attrDefaults_.fixed : &attrDefaults_.required;
2007-09-06 11:04:01 +02:00
string_type typeStr;
2002-06-21 13:16:28 +02:00
switch(type)
{
case XML_ATTRIBUTE_CDATA:
typeStr = attrTypes_.cdata;
break;
case XML_ATTRIBUTE_ID:
typeStr = attrTypes_.id;
break;
case XML_ATTRIBUTE_IDREF :
typeStr = attrTypes_.idref;
break;
case XML_ATTRIBUTE_IDREFS:
typeStr = attrTypes_.idrefs;
break;
case XML_ATTRIBUTE_ENTITY:
typeStr = attrTypes_.entity;
break;
case XML_ATTRIBUTE_ENTITIES:
typeStr = attrTypes_.entities;
break;
case XML_ATTRIBUTE_NMTOKEN:
typeStr = attrTypes_.nmtoken;
break;
case XML_ATTRIBUTE_NMTOKENS:
typeStr = attrTypes_.nmtokens;
break;
case XML_ATTRIBUTE_ENUMERATION:
typeStr = stringAttrEnum(tree, false);
break;
case XML_ATTRIBUTE_NOTATION:
2007-09-06 11:04:01 +02:00
string_adaptor::append(typeStr, attrTypes_.notation);
string_adaptor::append(typeStr, stringAttrEnum(tree, true));
2002-06-21 13:16:28 +02:00
break;
} // switch(type)
2007-09-06 11:04:01 +02:00
declHandler_->attributeDecl(string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(elem)),
string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(fullname)),
2002-06-21 13:16:28 +02:00
typeStr,
*defType,
2007-09-06 11:04:01 +02:00
string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(defaultValue)));
2002-06-21 13:16:28 +02:00
} // SAXattributeDecl
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
string_type libxml2_wrapper<string_type, T0, T1>::stringAttrEnum(xmlEnumerationPtr tree, bool leadingSpace) const
2002-06-21 13:16:28 +02:00
{
std::ostringstream os;
if(leadingSpace)
os << " ";
os << "(";
while(tree)
{
os << tree->name;
tree = tree->next;
if(tree)
os << " | ";
} // while
os << ")";
2007-09-06 11:04:01 +02:00
return string_adaptor::construct_from_utf8(os.str().c_str());
2002-06-21 13:16:28 +02:00
} // stringAttrEnum
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
void libxml2_wrapper<string_type, T0, T1>::SAXentityDecl(const xmlChar *name, int type, const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
2002-06-21 13:16:28 +02:00
{
if(!declHandler_)
return;
switch(type)
{
case 1: // internal
2007-09-06 11:04:01 +02:00
declHandler_->internalEntityDecl(string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(name)),
string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(content)));
2002-06-21 13:16:28 +02:00
break;
case 2: // external
2007-09-06 11:04:01 +02:00
declHandler_->externalEntityDecl(string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(name)),
string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(publicId)),
string_adaptor::construct_from_utf8(reinterpret_cast<const char*>(systemId)));
2002-06-21 13:16:28 +02:00
break;
} // switch
} // SAXentityDecl
2007-09-06 11:04:01 +02:00
template<class string_type, class T0, class T1>
xmlParserInputPtr libxml2_wrapper<string_type, T0, T1>::SAXresolveEntity(const xmlChar* publicId, const xmlChar* systemId)
2002-06-21 13:16:28 +02:00
{
if(!entityResolver_)
return xmlLoadExternalEntity(reinterpret_cast<const char*>(systemId),
reinterpret_cast<const char*>(publicId),
context_);
return 0;
} // SAXresolveEntity
} // namespace SAX
2007-09-05 11:49:18 +02:00
} // namespace Arabica
2002-06-21 13:16:28 +02:00
#endif