mirror of
https://github.com/jezhiggins/arabica
synced 2024-12-26 21:58:39 +01:00
952e71da02
Redundant, indeed deprecated, these days.
544 lines
20 KiB
C++
544 lines
20 KiB
C++
#ifndef JEZUK_SimpleDOM_DOCUMENTIMPL_H
|
|
#define JEZUK_SimpleDOM_DOCUMENTIMPL_H
|
|
|
|
|
|
#include <DOM/Document.hpp>
|
|
#include <DOM/Simple/ElementNSImpl.hpp>
|
|
#include <DOM/Simple/ProcessingInstructionImpl.hpp>
|
|
#include <DOM/Simple/DocumentFragmentImpl.hpp>
|
|
#include <DOM/Simple/CommentImpl.hpp>
|
|
#include <DOM/Simple/TextImpl.hpp>
|
|
#include <DOM/Simple/CDATASectionImpl.hpp>
|
|
#include <DOM/Simple/AttrNSImpl.hpp>
|
|
#include <DOM/Simple/EntityReferenceImpl.hpp>
|
|
#include <DOM/Simple/EntityImpl.hpp>
|
|
#include <DOM/Simple/NotationImpl.hpp>
|
|
#include <DOM/Simple/ElementByTagImpl.hpp>
|
|
#include <DOM/Simple/NodeImpl.hpp>
|
|
|
|
#include <set>
|
|
#include <algorithm>
|
|
|
|
namespace Arabica
|
|
{
|
|
namespace SimpleDOM
|
|
{
|
|
|
|
template<class stringT, class string_adaptorT>
|
|
class valueIs
|
|
{
|
|
public:
|
|
explicit valueIs(const stringT& value) : value_(value) { }
|
|
bool operator()(const AttrImpl<stringT, string_adaptorT>* node) const
|
|
{
|
|
return (node->getNodeValue() == value_);
|
|
} // operator()
|
|
|
|
private:
|
|
stringT value_;
|
|
}; // class valueIs
|
|
|
|
template<class stringT, class string_adaptorT>
|
|
class DocumentImpl : public DOM::Document_impl<stringT, string_adaptorT>,
|
|
public NodeImplWithChildren<stringT, string_adaptorT>
|
|
|
|
{
|
|
typedef NodeImpl<stringT, string_adaptorT> NodeImplT;
|
|
typedef AttrImpl<stringT, string_adaptorT> AttrImplT;
|
|
typedef ElementImpl<stringT, string_adaptorT> ElementImplT;
|
|
typedef NodeImplWithChildren<stringT, string_adaptorT> NodeWithChildrenT;
|
|
public:
|
|
typedef DOM::Node_impl<stringT, string_adaptorT> DOMNode_implT;
|
|
typedef DOM::Attr_impl<stringT, string_adaptorT> DOMAttr_implT;
|
|
typedef DOM::Element_impl<stringT, string_adaptorT> DOMElement_implT;
|
|
typedef DOM::Document_impl<stringT, string_adaptorT> DOMDocument_implT;
|
|
typedef DOM::DocumentType_impl<stringT, string_adaptorT> DOMDocumentType_implT;
|
|
typedef DOM::DOMImplementation<stringT, string_adaptorT> DOMDOMImplementationT;
|
|
|
|
DocumentImpl() :
|
|
NodeWithChildrenT(0),
|
|
documentElement_(0),
|
|
documentType_(0),
|
|
domImplementation_(),
|
|
namespaceURI_(),
|
|
qualifiedName_(),
|
|
changesCount_(0),
|
|
refCount_(0),
|
|
empty_()
|
|
{
|
|
NodeImplT::setOwnerDoc(this);
|
|
} // DocumentBaseImpl
|
|
|
|
DocumentImpl(DOMDOMImplementationT domImpl) :
|
|
NodeWithChildrenT(0),
|
|
documentElement_(0),
|
|
documentType_(0),
|
|
domImplementation_(domImpl),
|
|
namespaceURI_(),
|
|
qualifiedName_(),
|
|
changesCount_(0),
|
|
refCount_(0)
|
|
{
|
|
NodeImplT::setOwnerDoc(this);
|
|
} // DocumentBaseImpl
|
|
|
|
DocumentImpl(const stringT& namespaceURI,
|
|
const stringT& qualifiedName,
|
|
DOMDocumentType_implT* docType,
|
|
DOMDOMImplementationT domImpl) :
|
|
NodeWithChildrenT(0),
|
|
documentElement_(0),
|
|
documentType_(0),
|
|
domImplementation_(domImpl),
|
|
namespaceURI_(namespaceURI),
|
|
qualifiedName_(qualifiedName),
|
|
changesCount_(0),
|
|
refCount_(0)
|
|
{
|
|
NodeImplT::setOwnerDoc(this);
|
|
if(docType)
|
|
{
|
|
if(docType->getOwnerDocument() != 0)
|
|
throw DOM::DOMException(DOM::DOMException::WRONG_DOCUMENT_ERR);
|
|
appendChild(docType);
|
|
} // if(docType)
|
|
} // DocumentBaseImpl
|
|
|
|
virtual ~DocumentImpl()
|
|
{
|
|
for(typename std::set<NodeImplT*>::iterator n = orphans_.begin(); n != orphans_.end(); ++n)
|
|
delete *n;
|
|
} // ~DocumentImpl
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// Ref counting
|
|
virtual void addRef()
|
|
{
|
|
++refCount_;
|
|
} // addRef
|
|
|
|
virtual void releaseRef()
|
|
{
|
|
if(--refCount_ == 0)
|
|
delete this;
|
|
} // releaseRef
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// DOM::Document functions
|
|
virtual DOMDocumentType_implT* getDoctype() const
|
|
{
|
|
return documentType_;
|
|
} // getDocType
|
|
|
|
virtual DOMDOMImplementationT getImplementation() const
|
|
{
|
|
return domImplementation_;
|
|
} // getImplementation
|
|
|
|
virtual DOMElement_implT* getDocumentElement() const
|
|
{
|
|
return documentElement_;
|
|
} // getDocumentElement
|
|
|
|
virtual DOMElement_implT* createElement(const stringT& tagName) const
|
|
{
|
|
this->checkName(tagName);
|
|
return createElement_nocheck(tagName);
|
|
} // createElement
|
|
|
|
DOMElement_implT* createElement_nocheck(const stringT& tagName) const
|
|
{
|
|
ElementImplT* n =
|
|
new ElementImplT(const_cast<DocumentImpl*>(this), tagName);
|
|
orphaned(n);
|
|
return n;
|
|
} // createElement_nocheck
|
|
|
|
virtual DOM::DocumentFragment_impl<stringT, string_adaptorT>* createDocumentFragment() const
|
|
{
|
|
DocumentFragmentImpl<stringT, string_adaptorT>* n = new DocumentFragmentImpl<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this));
|
|
orphaned(n);
|
|
return n;
|
|
} // createDocumentFragment
|
|
|
|
virtual DOM::Text_impl<stringT, string_adaptorT>* createTextNode(const stringT& data) const
|
|
{
|
|
TextImpl<stringT, string_adaptorT>* n = new TextImpl<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this), data);
|
|
orphaned(n);
|
|
return n;
|
|
} // createTextNode
|
|
|
|
virtual DOM::Comment_impl<stringT, string_adaptorT>* createComment(const stringT& data) const
|
|
{
|
|
CommentImpl<stringT, string_adaptorT>* n = new CommentImpl<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this), data);
|
|
orphaned(n);
|
|
return n;
|
|
} // createComment
|
|
|
|
virtual DOM::CDATASection_impl<stringT, string_adaptorT>* createCDATASection(const stringT& data) const
|
|
{
|
|
CDATASectionImpl<stringT, string_adaptorT>* n = new CDATASectionImpl<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this), data);
|
|
orphaned(n);
|
|
return n;
|
|
} // createCDATASection
|
|
|
|
virtual DOM::ProcessingInstruction_impl<stringT, string_adaptorT>* createProcessingInstruction(const stringT& target, const stringT& data) const
|
|
{
|
|
this->checkName(target);
|
|
this->checkChars(data);
|
|
return createProcessingInstruction_nocheck(target, data);
|
|
} // createProcessingInstruction
|
|
|
|
DOM::ProcessingInstruction_impl<stringT, string_adaptorT>* createProcessingInstruction_nocheck(const stringT& target, const stringT& data) const
|
|
{
|
|
ProcessingInstructionImpl<stringT, string_adaptorT>* n = new ProcessingInstructionImpl<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this), target, data);
|
|
orphaned(n);
|
|
return n;
|
|
} // createProcessingInstruction_nocheck
|
|
|
|
virtual DOMAttr_implT* createAttribute(const stringT& name) const
|
|
{
|
|
this->checkName(name);
|
|
return createAttribute_nocheck(name);
|
|
} // createAttribute
|
|
|
|
DOMAttr_implT* createAttribute_nocheck(const stringT& name) const
|
|
{
|
|
AttrImpl<stringT, string_adaptorT>* n = new AttrImpl<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this), name);
|
|
orphaned(n);
|
|
return n;
|
|
} // createAttribute_nocheck
|
|
|
|
virtual DOM::EntityReference_impl<stringT, string_adaptorT>* createEntityReference(const stringT& name) const
|
|
{
|
|
this->checkName(name);
|
|
return createEntityReference_nocheck(name);
|
|
} // createEntityRef
|
|
|
|
DOM::EntityReference_impl<stringT, string_adaptorT>* createEntityReference_nocheck(const stringT& name) const
|
|
{
|
|
EntityReferenceImpl<stringT, string_adaptorT>* n = new EntityReferenceImpl<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this), name);
|
|
if((documentType_ != 0) && (documentType_->getEntities()->getNamedItem(name) != 0))
|
|
{
|
|
DOMNode_implT* entity = documentType_->getEntities()->getNamedItem(name);
|
|
for(DOMNode_implT* child = entity->getFirstChild(); child != 0; child = child->getNextSibling())
|
|
n->appendChild(importNode(child, true));
|
|
} // if ...
|
|
orphaned(n);
|
|
n->setReadOnly(true);
|
|
return n;
|
|
} // createEntityReference
|
|
|
|
virtual DOM::NodeList_impl<stringT, string_adaptorT>* getElementsByTagName(const stringT& tagname) const
|
|
{
|
|
return new ElementByTagList<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this),
|
|
const_cast<DocumentImpl*>(this),
|
|
tagname);
|
|
} // getElementsByTagName
|
|
|
|
virtual DOMNode_implT* importNode(DOMNode_implT* importedNode, bool deep) const
|
|
{
|
|
DOMNode_implT* newNode = 0;
|
|
|
|
switch(importedNode->getNodeType())
|
|
{
|
|
case DOM::Node_base::ATTRIBUTE_NODE:
|
|
if(string_adaptorT::empty(importedNode->getLocalName()))
|
|
newNode = createAttribute_nocheck(importedNode->getNodeName());
|
|
else
|
|
newNode = createAttributeNS_nocheck(importedNode->getNamespaceURI(), importedNode->getNodeName());
|
|
deep = true;
|
|
break;
|
|
case DOM::Node_base::DOCUMENT_FRAGMENT_NODE:
|
|
newNode = createDocumentFragment();
|
|
break;
|
|
case DOM::Node_base::DOCUMENT_NODE:
|
|
throw DOM::DOMException(DOM::DOMException::NOT_SUPPORTED_ERR);
|
|
case DOM::Node_base::DOCUMENT_TYPE_NODE:
|
|
throw DOM::DOMException(DOM::DOMException::NOT_SUPPORTED_ERR);
|
|
case DOM::Node_base::ELEMENT_NODE:
|
|
{
|
|
DOMElement_implT* elem;
|
|
if(string_adaptorT::empty(importedNode->getLocalName()))
|
|
elem = createElement_nocheck(importedNode->getNodeName());
|
|
else
|
|
elem = createElementNS_nocheck(importedNode->getNamespaceURI(), importedNode->getNodeName());
|
|
|
|
const DOM::NamedNodeMap_impl<stringT, string_adaptorT>* attrs = importedNode->getAttributes();
|
|
if(attrs)
|
|
for(unsigned int i = 0; i < attrs->getLength(); ++i)
|
|
{
|
|
DOMAttr_implT* a = dynamic_cast<DOMAttr_implT*>(attrs->item(i));
|
|
if(a->getSpecified())
|
|
{
|
|
DOMAttr_implT* newA = dynamic_cast<DOMAttr_implT*>(importNode(a, true));
|
|
if(string_adaptorT::empty(a->getLocalName()))
|
|
elem->setAttributeNode(newA);
|
|
else
|
|
elem->setAttributeNodeNS(newA);
|
|
} // if ...
|
|
} // for
|
|
newNode = elem;
|
|
}
|
|
break;
|
|
case DOM::Node_base::ENTITY_NODE:
|
|
{
|
|
DOM::Entity_impl<stringT, string_adaptorT>* entity = dynamic_cast<DOM::Entity_impl<stringT, string_adaptorT>*>(importedNode);
|
|
newNode = new EntityImpl<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this),
|
|
entity->getNodeName(),
|
|
entity->getPublicId(),
|
|
entity->getSystemId(),
|
|
entity->getNotationName());
|
|
}
|
|
break;
|
|
case DOM::Node_base::ENTITY_REFERENCE_NODE:
|
|
newNode = createEntityReference_nocheck(importedNode->getNodeName());
|
|
deep = false;
|
|
break;
|
|
case DOM::Node_base::NOTATION_NODE:
|
|
{
|
|
DOM::Notation_impl<stringT, string_adaptorT>* entity = dynamic_cast<DOM::Notation_impl<stringT, string_adaptorT>*>(importedNode);
|
|
newNode = new NotationImpl<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this),
|
|
entity->getNodeName(),
|
|
entity->getPublicId(),
|
|
entity->getSystemId());
|
|
}
|
|
break;
|
|
case DOM::Node_base::PROCESSING_INSTRUCTION_NODE:
|
|
newNode = createProcessingInstruction_nocheck(importedNode->getNodeName(), importedNode->getNodeValue());
|
|
break;
|
|
case DOM::Node_base::TEXT_NODE:
|
|
newNode = createTextNode(importedNode->getNodeValue());
|
|
break;
|
|
case DOM::Node_base::CDATA_SECTION_NODE:
|
|
newNode = createCDATASection(importedNode->getNodeValue());
|
|
break;
|
|
case DOM::Node_base::COMMENT_NODE:
|
|
newNode = createComment(importedNode->getNodeValue());
|
|
break;
|
|
default:
|
|
throw std::runtime_error("Bad node type value in importNode");
|
|
} // switch
|
|
|
|
if(deep)
|
|
{
|
|
for(DOMNode_implT* child = importedNode->getFirstChild(); child != 0; child = child->getNextSibling())
|
|
newNode->appendChild(importNode(child, true));
|
|
} // if(deep)
|
|
|
|
if(newNode->getNodeType() == DOM::Node_base::ENTITY_NODE)
|
|
dynamic_cast<NodeImplT*>(newNode)->setReadOnly(true);
|
|
orphaned(dynamic_cast<NodeImplT*>(newNode));
|
|
|
|
return newNode;
|
|
} // importNode
|
|
|
|
virtual DOMElement_implT* createElementNS(const stringT& namespaceURI, const stringT& qualifiedName) const
|
|
{
|
|
this->checkName(qualifiedName);
|
|
return createElementNS_nocheck(namespaceURI, qualifiedName);
|
|
} // createElementNS
|
|
|
|
DOMElement_implT* createElementNS_nocheck(const stringT& namespaceURI, const stringT& qualifiedName) const
|
|
{
|
|
ElementNSImpl<stringT, string_adaptorT>* n =
|
|
new ElementNSImpl<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this), namespaceURI, !string_adaptorT::empty(namespaceURI), qualifiedName);
|
|
orphaned(n);
|
|
return n;
|
|
} // createElementNS
|
|
|
|
virtual DOMAttr_implT* createAttributeNS(const stringT& namespaceURI, const stringT& qualifiedName) const
|
|
{
|
|
this->checkName(qualifiedName);
|
|
return createAttributeNS_nocheck(namespaceURI, qualifiedName);
|
|
} // createAttributeNS
|
|
|
|
virtual DOMAttr_implT* createAttributeNS_nocheck(const stringT& namespaceURI, const stringT& qualifiedName) const
|
|
{
|
|
AttrNSImpl<stringT, string_adaptorT>* n = new AttrNSImpl<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this), namespaceURI, !string_adaptorT::empty(namespaceURI), qualifiedName);
|
|
orphaned(n);
|
|
return n;
|
|
} // createAttributeNS_nocheck
|
|
|
|
virtual DOM::NodeList_impl<stringT, string_adaptorT>* getElementsByTagNameNS(const stringT& namespaceURI, const stringT& localName) const
|
|
{
|
|
return new ElementByTagList<stringT, string_adaptorT>(const_cast<DocumentImpl*>(this),
|
|
const_cast<DocumentImpl*>(this),
|
|
namespaceURI, localName);
|
|
} // getElementsByTagNameNS
|
|
|
|
virtual DOMElement_implT* getElementById(const stringT& elementId) const
|
|
{
|
|
typename std::set<AttrImplT*>::const_iterator i = std::find_if(idNodes_.begin(), idNodes_.end(), valueIs<stringT, string_adaptorT>(elementId));
|
|
if(i == idNodes_.end())
|
|
return 0;
|
|
return (*i)->getOwnerElement();
|
|
} // getElementById
|
|
|
|
////////////////////////////////////////////////////////
|
|
// DOM Node methods
|
|
virtual typename DOM::Node_base::Type getNodeType() const
|
|
{
|
|
return DOM::Node_base::DOCUMENT_NODE;
|
|
} // getNodeType
|
|
|
|
virtual DOMNode_implT* getParentNode() const { return 0; }
|
|
|
|
virtual DOMDocument_implT* getOwnerDocument() const { return 0; }
|
|
|
|
virtual const stringT& getNodeName() const
|
|
{
|
|
static const stringT doc = string_adaptorT::construct_from_utf8("#document");
|
|
return doc;
|
|
} // getNodeName
|
|
|
|
virtual DOMNode_implT* insertBefore(DOMNode_implT* newChild, DOMNode_implT* refChild)
|
|
{
|
|
if((newChild->getNodeType() == DOM::Node_base::ELEMENT_NODE) && (documentElement_ != 0))
|
|
throw DOM::DOMException(DOM::DOMException::HIERARCHY_REQUEST_ERR);
|
|
if((newChild->getNodeType() == DOM::Node_base::DOCUMENT_TYPE_NODE) && (documentType_ != 0))
|
|
throw DOM::DOMException(DOM::DOMException::HIERARCHY_REQUEST_ERR);
|
|
|
|
DOMNode_implT* result = NodeWithChildrenT::insertBefore(newChild, refChild);
|
|
|
|
if((newChild->getNodeType() == DOM::Node_base::ELEMENT_NODE) && (documentElement_ == 0))
|
|
documentElement_ = dynamic_cast<DOMElement_implT*>(newChild);
|
|
if((newChild->getNodeType() == DOM::Node_base::DOCUMENT_TYPE_NODE) && (documentType_ == 0))
|
|
documentType_ = dynamic_cast<DOMDocumentType_implT*>(newChild);
|
|
|
|
return result;
|
|
} // insertBefore
|
|
|
|
virtual DOMNode_implT* replaceChild(DOMNode_implT* newChild, DOMNode_implT* oldChild)
|
|
{
|
|
checkChildType(newChild);
|
|
|
|
if((newChild->getNodeType() == DOM::Node_base::DOCUMENT_TYPE_NODE) && (documentType_ == oldChild))
|
|
throw DOM::DOMException(DOM::DOMException::HIERARCHY_REQUEST_ERR);
|
|
if((newChild->getNodeType() == DOM::Node_base::ELEMENT_NODE) &&
|
|
(documentElement_ != 0) &&
|
|
(documentElement_ != oldChild))
|
|
throw DOM::DOMException(DOM::DOMException::HIERARCHY_REQUEST_ERR);
|
|
|
|
DOMNode_implT* result = NodeWithChildrenT::replaceChild(newChild, oldChild);
|
|
|
|
if((newChild->getNodeType() == DOM::Node_base::ELEMENT_NODE) &&
|
|
((documentElement_ == 0) || (documentElement_ == oldChild)))
|
|
documentElement_ = dynamic_cast<DOMElement_implT*>(newChild);
|
|
|
|
return result;
|
|
} // replaceChild
|
|
|
|
virtual DOMNode_implT* removeChild(DOMNode_implT* oldChild)
|
|
{
|
|
if(documentType_ == oldChild)
|
|
throw DOM::DOMException(DOM::DOMException::HIERARCHY_REQUEST_ERR);
|
|
DOMNode_implT* result = NodeWithChildrenT::removeChild(oldChild);
|
|
|
|
if(documentElement_ == oldChild)
|
|
documentElement_ = static_cast<DOMElement_implT*>(0);
|
|
|
|
return result;
|
|
} // removeChild
|
|
|
|
virtual DOMNode_implT* appendChild(DOMNode_implT* newChild)
|
|
{
|
|
return insertBefore(newChild, 0);
|
|
} // appendChild
|
|
|
|
virtual DOMNode_implT* cloneNode(bool deep) const
|
|
{
|
|
DocumentImpl* clone = new DocumentImpl(namespaceURI_, qualifiedName_, 0, domImplementation_);
|
|
if(documentType_ != 0)
|
|
{
|
|
DocumentTypeImpl<stringT, string_adaptorT>* dt = dynamic_cast<DocumentTypeImpl<stringT, string_adaptorT>*>(documentType_->cloneNode(true));
|
|
dt->setOwnerDoc(clone);
|
|
clone->appendChild(dt);
|
|
}
|
|
|
|
if(deep)
|
|
for(DOMNode_implT* child = NodeWithChildrenT::getFirstChild(); child != 0; child = child->getNextSibling())
|
|
if((documentType_ != child) && (child != clone->getDocumentElement()))
|
|
clone->appendChild(clone->importNode(child, true));
|
|
|
|
return clone;
|
|
} // cloneNode
|
|
|
|
////////////////////////////
|
|
// extensions
|
|
void markChanged() { ++changesCount_; }
|
|
unsigned long changes() const { return changesCount_; }
|
|
|
|
void orphaned(NodeImplT* node) const
|
|
{
|
|
orphans_.insert(node);
|
|
} // orphaned
|
|
|
|
bool isOrphaned(NodeImplT* node) const
|
|
{
|
|
return orphans_.find(node) != orphans_.end();
|
|
} // isOrphaned
|
|
|
|
void purge(NodeImplT* node)
|
|
{
|
|
orphans_.erase(node);
|
|
delete node;
|
|
} // purge
|
|
|
|
void adopted(NodeImplT* node)
|
|
{
|
|
typename std::set<NodeImplT*>::iterator n = orphans_.find(node);
|
|
if(n != orphans_.end())
|
|
orphans_.erase(n);
|
|
} // adopted
|
|
|
|
void setElementId(AttrImplT* attr)
|
|
{
|
|
idNodes_.insert(attr);
|
|
} // setElementId
|
|
|
|
void removeElementId(AttrImplT* attr)
|
|
{
|
|
typename std::set<AttrImplT*>::iterator n = idNodes_.find(attr);
|
|
if(n != idNodes_.end())
|
|
idNodes_.erase(n);
|
|
} // removeElementId
|
|
|
|
stringT const* stringPool(const stringT& str) const
|
|
{
|
|
return &(*stringPool_.insert(str).first);
|
|
} // stringPool
|
|
|
|
const stringT& empty_string() const { return empty_; }
|
|
|
|
private:
|
|
void checkChildType(DOMNode_implT* child)
|
|
{
|
|
typename DOM::Node_base::Type type = child->getNodeType();
|
|
if((type != DOM::Node_base::ELEMENT_NODE) &&
|
|
(type != DOM::Node_base::PROCESSING_INSTRUCTION_NODE) &&
|
|
(type != DOM::Node_base::COMMENT_NODE) &&
|
|
(type != DOM::Node_base::DOCUMENT_TYPE_NODE))
|
|
throw DOM::DOMException(DOM::DOMException::HIERARCHY_REQUEST_ERR);
|
|
} // checkChildType
|
|
|
|
private:
|
|
DOMElement_implT* documentElement_;
|
|
DOMDocumentType_implT* documentType_;
|
|
DOMDOMImplementationT domImplementation_;
|
|
stringT namespaceURI_;
|
|
stringT qualifiedName_;
|
|
unsigned long changesCount_;
|
|
unsigned long refCount_;
|
|
|
|
mutable std::set<NodeImplT*> orphans_;
|
|
std::set<AttrImplT*> idNodes_;
|
|
mutable std::set<stringT> stringPool_;
|
|
const stringT empty_;
|
|
}; // class DocumentImpl
|
|
|
|
} // namespace SAX2DOM
|
|
} // namespace Arabica
|
|
|
|
#endif
|
|
// end of file
|