?? dombuilder.cpp
字號:
//
// DOMBuilder.cpp
//
// $Id: //poco/Main/XML/src/DOMBuilder.cpp#5 $
//
// Copyright (c) 2004, Guenter Obiltschnig/Applied Informatics.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Redistributions in any form must be accompanied by information on
// how to obtain complete source code for this software and any
// accompanying software that uses this software. The source code
// must either be included in the distribution or be available for no
// more than the cost of distribution plus a nominal fee, and must be
// freely redistributable under reasonable conditions. For an
// executable file, complete source code means the source code for all
// modules it contains. It does not include source code for modules or
// files that typically accompany the major components of the operating
// system on which the executable file runs.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#include "DOM/DOMBuilder.h"
#include "DOM/Document.h"
#include "DOM/DocumentType.h"
#include "DOM/CharacterData.h"
#include "DOM/Text.h"
#include "DOM/Comment.h"
#include "DOM/CDATASection.h"
#include "DOM/Element.h"
#include "DOM/Attr.h"
#include "DOM/Entity.h"
#include "DOM/EntityReference.h"
#include "DOM/Notation.h"
#include "DOM/ProcessingInstruction.h"
#include "DOM/AutoPtr.h"
#include "SAX/XMLReader.h"
#include "SAX/AttributesImpl.h"
XML_BEGIN
const XMLString DOMBuilder::EMPTY_STRING;
DOMBuilder::DOMBuilder(XMLReader& xmlReader, NamePool* pNamePool):
_xmlReader(xmlReader),
_pNamePool(pNamePool),
_pDocument(0),
_pParent(0),
_pPrevious(0),
_inCDATA(false),
_namespaces(true)
{
_xmlReader.setContentHandler(this);
_xmlReader.setDTDHandler(this);
_xmlReader.setProperty(XMLReader::PROPERTY_LEXICAL_HANDLER, static_cast<LexicalHandler*>(this));
if (_pNamePool) _pNamePool->duplicate();
}
DOMBuilder::~DOMBuilder()
{
if (_pNamePool) _pNamePool->release();
}
Document* DOMBuilder::parse(const XMLString& uri)
{
setupParse();
_pDocument->suspendEvents();
try
{
_xmlReader.parse(uri);
}
catch (...)
{
_pDocument->release();
_pDocument = 0;
_pParent = 0;
_pPrevious = 0;
throw;
}
_pDocument->resumeEvents();
_pDocument->collectGarbage();
return _pDocument;
}
Document* DOMBuilder::parse(InputSource* pInputSource)
{
setupParse();
_pDocument->suspendEvents();
try
{
_xmlReader.parse(pInputSource);
}
catch (...)
{
_pDocument->release();
_pDocument = 0;
_pParent = 0;
_pPrevious = 0;
throw;
}
_pDocument->resumeEvents();
_pDocument->collectGarbage();
return _pDocument;
}
void DOMBuilder::setupParse()
{
_pDocument = new Document(_pNamePool);
_pParent = _pDocument;
_pPrevious = 0;
_inCDATA = false;
_namespaces = _xmlReader.getFeature(XMLReader::FEATURE_NAMESPACES);
}
inline void DOMBuilder::appendNode(AbstractNode* pNode)
{
if (_pPrevious && _pPrevious != _pParent)
{
_pPrevious->_pNext = pNode;
pNode->_pParent = _pParent;
pNode->duplicate();
}
else _pParent->appendChild(pNode);
_pPrevious = pNode;
}
void DOMBuilder::notationDecl(const XMLString& name, const XMLString* publicId, const XMLString* systemId)
{
DocumentType* pDoctype = _pDocument->getDoctype();
if (pDoctype)
{
AutoPtr<Notation> pNotation = _pDocument->createNotation(name, (publicId ? *publicId : EMPTY_STRING), (systemId ? *systemId : EMPTY_STRING));
pDoctype->appendChild(pNotation);
}
}
void DOMBuilder::unparsedEntityDecl(const XMLString& name, const XMLString* publicId, const XMLString& systemId, const XMLString& notationName)
{
DocumentType* pDoctype = _pDocument->getDoctype();
if (pDoctype)
{
AutoPtr<Entity> pEntity = _pDocument->createEntity(name, publicId ? *publicId : EMPTY_STRING, systemId, notationName);
pDoctype->appendChild(pEntity);
}
}
void DOMBuilder::setDocumentLocator(const Locator* loc)
{
}
void DOMBuilder::startDocument()
{
}
void DOMBuilder::endDocument()
{
}
void DOMBuilder::startElement(const XMLString& uri, const XMLString& localName, const XMLString& qname, const Attributes& attributes)
{
AutoPtr<Element> pElem = _namespaces ? _pDocument->createElementNS(uri, qname.empty() ? localName : qname) : _pDocument->createElement(qname);
const AttributesImpl& attrs = dynamic_cast<const AttributesImpl&>(attributes);
for (AttributesImpl::iterator it = attrs.begin(); it != attrs.end(); ++it)
{
AutoPtr<Attr> pAttr = new Attr(_pDocument, 0, it->namespaceURI, it->localName, it->qname, it->value, it->specified);
if (_namespaces)
pElem->setAttributeNodeNS(pAttr);
else
pElem->setAttributeNode(pAttr);
}
appendNode(pElem);
_pParent = pElem;
}
void DOMBuilder::endElement(const XMLString& uri, const XMLString& localName, const XMLString& qname)
{
_pPrevious = _pParent;
_pParent = static_cast<AbstractContainerNode*>(_pParent->parentNode());
}
void DOMBuilder::characters(const XMLChar ch[], int start, int length)
{
if (_inCDATA)
{
if (_pPrevious && _pPrevious->nodeType() == Node::CDATA_SECTION_NODE)
{
static_cast<CDATASection*>(_pPrevious)->appendData(XMLString(ch + start, length));
}
else
{
AutoPtr<CDATASection> pCDATA = _pDocument->createCDATASection(XMLString(ch + start, length));
appendNode(pCDATA);
}
}
else
{
if (_pPrevious && _pPrevious->nodeType() == Node::TEXT_NODE)
{
static_cast<Text*>(_pPrevious)->appendData(XMLString(ch + start, length));
}
else
{
AutoPtr<Text> pText = _pDocument->createTextNode(XMLString(ch + start, length));
appendNode(pText);
}
}
}
void DOMBuilder::ignorableWhitespace(const XMLChar ch[], int start, int length)
{
characters(ch, start, length);
}
void DOMBuilder::processingInstruction(const XMLString& target, const XMLString& data)
{
AutoPtr<ProcessingInstruction> pPI = _pDocument->createProcessingInstruction(target, data);
appendNode(pPI);
}
void DOMBuilder::startPrefixMapping(const XMLString& prefix, const XMLString& uri)
{
}
void DOMBuilder::endPrefixMapping(const XMLString& prefix)
{
}
void DOMBuilder::skippedEntity(const XMLString& name)
{
AutoPtr<EntityReference> pER = _pDocument->createEntityReference(name);
appendNode(pER);
}
void DOMBuilder::startDTD(const XMLString& name, const XMLString& publicId, const XMLString& systemId)
{
AutoPtr<DocumentType> pDoctype = new DocumentType(_pDocument, name, publicId, systemId);
_pDocument->setDoctype(pDoctype);
}
void DOMBuilder::endDTD()
{
}
void DOMBuilder::startEntity(const XMLString& name)
{
}
void DOMBuilder::endEntity(const XMLString& name)
{
}
void DOMBuilder::startCDATA()
{
_inCDATA = true;
}
void DOMBuilder::endCDATA()
{
_inCDATA = false;
}
void DOMBuilder::comment(const XMLChar ch[], int start, int length)
{
AutoPtr<Comment> pComment = _pDocument->createComment(XMLString(ch + start, length));
appendNode(pComment);
}
XML_END
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -