blob: 544f48df4d060d2655cfdbd3614c221342894465 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Class header file.
#include "FormatterToXercesDOM.hpp"
#include <cassert>
#include <xercesc/sax/AttributeList.hpp>
#include <xercesc/dom/DOMCDATASection.hpp>
#include <xercesc/dom/DOMComment.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMDocumentFragment.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/dom/DOMEntityReference.hpp>
#include <xercesc/dom/DOMProcessingInstruction.hpp>
#include <xercesc/dom/DOMText.hpp>
#include <xalanc/XalanDOM/XalanDOMString.hpp>
#include <xalanc/DOMSupport/DOMServices.hpp>
#include <xalanc/PlatformSupport/DOMStringHelper.hpp>
#include <xalanc/PlatformSupport/PrefixResolver.hpp>
#include "XercesDOMException.hpp"
namespace XALAN_CPP_NAMESPACE {
const XalanDOMString FormatterToXercesDOM::s_emptyString(XalanMemMgrs::getDummyMemMgr());
FormatterToXercesDOM::FormatterToXercesDOM(
DOMDocument_Type* doc,
DOMDocumentFragmentType* docFrag,
DOMElementType* currentElement,
MemoryManager& theManager) :
FormatterListener(OUTPUT_METHOD_DOM),
m_doc(doc),
m_docFrag(docFrag),
m_currentElem(currentElement),
m_elemStack(theManager),
m_buffer(theManager),
m_textBuffer(theManager)
{
assert(m_doc != 0 && m_docFrag != 0);
}
FormatterToXercesDOM::FormatterToXercesDOM(
DOMDocument_Type* doc,
DOMElementType* elem,
MemoryManager& theManager) :
FormatterListener(OUTPUT_METHOD_DOM),
m_doc(doc),
m_docFrag(0),
m_currentElem(elem),
m_elemStack(theManager),
m_buffer(theManager),
m_textBuffer(theManager)
{
assert(m_doc != 0);
}
FormatterToXercesDOM::~FormatterToXercesDOM()
{
}
void
FormatterToXercesDOM::setDocumentLocator(const Locator* const /* locator */)
{
// No action for the moment.
}
void
FormatterToXercesDOM::startDocument()
{
// No action for the moment.
}
void
FormatterToXercesDOM::endDocument()
{
try
{
// Process any remaining text, in case we're
// appending to a DOMDocumentFragment.
processAccumulatedText();
}
catch(const xercesc::DOMException& theException)
{
throw XercesDOMException(theException);
}
}
void
FormatterToXercesDOM::startElement(
const XMLCh* const name,
AttributeListType& attrs)
{
try
{
processAccumulatedText();
DOMElementType* const elem = createElement(name, attrs);
assert(elem != 0);
append(elem);
m_elemStack.push_back(m_currentElem);
m_currentElem = elem;
}
catch(const xercesc::DOMException& theException)
{
throw XercesDOMException(theException);
}
}
void
FormatterToXercesDOM::endElement(const XMLCh* const /* name */)
{
try
{
processAccumulatedText();
if(m_elemStack.empty() == false)
{
m_currentElem = m_elemStack.back();
m_elemStack.pop_back();
}
else
{
m_currentElem = 0;
}
}
catch(const xercesc::DOMException& theException)
{
throw XercesDOMException(theException);
}
}
void
FormatterToXercesDOM::characters(
const XMLCh* const chars,
const size_type length)
{
m_textBuffer.append(chars, length);
}
void
FormatterToXercesDOM::charactersRaw(
const XMLCh* const chars,
const size_type length)
{
try
{
processAccumulatedText();
cdata(chars, length);
}
catch(const xercesc::DOMException& theException)
{
throw XercesDOMException(theException);
}
}
void
FormatterToXercesDOM::entityReference(const XMLCh* const name)
{
try
{
processAccumulatedText();
append(m_doc->createEntityReference(name));
}
catch(const xercesc::DOMException& theException)
{
throw XercesDOMException(theException);
}
}
void
FormatterToXercesDOM::ignorableWhitespace(
const XMLCh* const chars,
const size_type length)
{
try
{
processAccumulatedText();
m_buffer.assign(chars, length);
append(m_doc->createTextNode(m_buffer.c_str()));
}
catch(const xercesc::DOMException& theException)
{
throw XercesDOMException(theException);
}
}
void
FormatterToXercesDOM::processingInstruction(
const XMLCh* const target,
const XMLCh* const data)
{
try
{
processAccumulatedText();
append(m_doc->createProcessingInstruction(target, data));
}
catch(const xercesc::DOMException& theException)
{
throw XercesDOMException(theException);
}
}
void
FormatterToXercesDOM::resetDocument()
{
}
void
FormatterToXercesDOM::comment(const XMLCh* const data)
{
try
{
processAccumulatedText();
append(m_doc->createComment(data));
}
catch(const xercesc::DOMException& theException)
{
throw XercesDOMException(theException);
}
}
void
FormatterToXercesDOM::cdata(
const XMLCh* const ch,
const size_type length)
{
try
{
processAccumulatedText();
m_buffer.assign(ch, length);
append(m_doc->createCDATASection(m_buffer.c_str()));
}
catch(const xercesc::DOMException& theException)
{
throw XercesDOMException(theException);
}
}
void
FormatterToXercesDOM::append(DOMNodeType* newNode)
{
assert(newNode != 0);
if(0 != m_currentElem)
{
m_currentElem->appendChild(newNode);
}
else if(0 != m_docFrag)
{
m_docFrag->appendChild(newNode);
}
else
{
m_doc->appendChild(newNode);
}
}
DOMElementType*
FormatterToXercesDOM::createElement(
const XalanDOMChar* theElementName,
AttributeListType& attrs)
{
DOMElementType* theElement = 0;
if (m_prefixResolver == 0)
{
theElement = m_doc->createElement(theElementName);
addAttributes(theElement, attrs);
}
else
{
// Check for the namespace...
const XalanDOMString* const theNamespace =
DOMServices::getNamespaceForPrefix(theElementName, *m_prefixResolver, false, m_buffer);
if (theNamespace == 0 || theNamespace->empty() == true)
{
theElement = m_doc->createElement(theElementName);
}
else
{
theElement = m_doc->createElementNS(theNamespace->c_str(), theElementName);
}
addAttributes(theElement, attrs);
}
return theElement;
}
void
FormatterToXercesDOM::addAttributes(
DOMElementType* theElement,
AttributeListType& attrs)
{
const XalanSize_t nAtts = attrs.getLength();
if (m_prefixResolver == 0)
{
for (XalanSize_t i = 0; i < nAtts; i++)
{
theElement->setAttribute(attrs.getName(i), attrs.getValue(i));
}
}
else
{
for (XalanSize_t i = 0; i < nAtts; i++)
{
const XalanDOMChar* const theName = attrs.getName(i);
assert(theName != 0);
// Check for the namespace...
const XalanDOMString* const theNamespace =
DOMServices::getNamespaceForPrefix(theName, *m_prefixResolver, true, m_buffer);
if (theNamespace == 0 || theNamespace->empty() == true)
{
theElement->setAttribute(theName, attrs.getValue(i));
}
else
{
theElement->setAttributeNS(theNamespace->c_str(), theName, attrs.getValue(i));
}
}
}
}
void
FormatterToXercesDOM::processAccumulatedText()
{
if (m_textBuffer.empty() == false)
{
append(m_doc->createTextNode(m_textBuffer.c_str()));
m_textBuffer.clear();
}
}
}