DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://nagoya.apache.org/bugzilla/show_bug.cgi?id=26374>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=26374 Transformation ignores xsl:output doctype declaration when transforming to DOM tree Summary: Transformation ignores xsl:output doctype declaration when transforming to DOM tree Product: XalanC Version: 1.5 Platform: All OS/Version: All Status: NEW Severity: Normal Priority: Other Component: XalanC AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] When using a FormatterToDOM or FormatterToXercesDOM then the result doesn't have a doctype node after transformation even if the doctype-system attribute on the xsl:output element is specified. When using other formatters (FormatterToXML for example) then the doctype node is generated. I have fixed it in our version (Xalan 1.5) like this: In FormatterListener.hpp I added a new method: virtual void documentType( const XMLCh* const systemID, const XMLCh* const publicID); And implemented it in FormatterListener.cpp as an empty method: void FormatterListener::documentType( const XMLCh* const /* systemID */, const XMLCh* const /* publicID */) { // Do nothing } I then added code in StylesheetRoot.cpp that calls the new method: FormatterListener* StylesheetRoot::setupFormatterListener( XSLTResultTarget& outputTarget, StylesheetExecutionContext& executionContext) const { FormatterListener* flistener = outputTarget.getFormatterListener(); if (flistener != 0) { // Do encoding stuff here... /* NEW CODE START */ // Do documenttype stuff if (m_doctypeSystem.empty() == false) flistener->documentType(m_doctypeSystem.c_str(), m_doctypePublic.c_str()); /* NEW CODE END */ } else if(0 != outputTarget.getCharacterStream() || 0 != outputTarget.getByteStream() || 0 != length(outputTarget.getFileName())) { Then I added the method to FormatterToDOM.cpp and FormatterToXercesDOM.cpp and two extra members: virtual void documentType( const XMLCh* const systemID, const XMLCh* const publicID); XalanDOMString m_systemID; XalanDOMString m_publicID; Then I implemented the new method like this: void FormatterToDOM::documentType( const XMLCh* const systemID, const XMLCh* const publicID) { assign(m_systemID, systemID); assign(m_publicID, publicID); } ...and... void FormatterToXercesDOM::documentType( const XMLCh* const systemID, const XMLCh* const publicID) { assign(m_systemID, systemID); assign(m_publicID, publicID); } And finally I changed the following code in FormatterToDOM and FormatterToXercesDOM: void FormatterToDOM::append(XalanNode* newNode) { assert(newNode != 0); if(0 != m_currentElem) { m_currentElem->appendChild(newNode); } else if(0 != m_docFrag) { m_docFrag->appendChild(newNode); } else { /* NEW CODE START */ if (m_doc->getDocumentElement() == 0 && newNode->getNodeType() == XalanNode::ELEMENT_NODE && m_systemID.empty() == false) { XalanDocumentType* poOldDocType = m_doc->getDoctype(); XalanDocumentType* poNewDocType = m_doc- >getImplementation()->createDocumentType(newNode->getNodeName(), m_publicID, m_systemID); if (poOldDocType) m_doc->replaceChild (reinterpret_cast<XalanNode*>(poNewDocType), reinterpret_cast<XalanNode*> (poOldDocType)); else m_doc->appendChild(reinterpret_cast<XalanNode*> (poNewDocType)); m_systemID.clear(); m_publicID.clear(); } /* NEW CODE END */ m_doc->appendChild(newNode); } } ... and ... 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 { /* NEW CODE START */ if (m_doc->getDocumentElement() == 0 && newNode->getNodeType() == DOMNodeType::ELEMENT_NODE && m_systemID.empty() == false) { DOMDocumentType* poOldDocType = m_doc->getDoctype(); DOMDocumentType* poNewDocType = m_doc- >getImplementation()->createDocumentType(newNode->getNodeName(), m_publicID.c_str(), m_systemID.c_str()); if (poOldDocType) m_doc->replaceChild(reinterpret_cast<DOMNode*> (poNewDocType), reinterpret_cast<DOMNode*>(poOldDocType)); else m_doc->appendChild(reinterpret_cast<DOMNode*> (poNewDocType)); m_systemID.clear(); m_publicID.clear(); } /* NEW CODE END */ m_doc->appendChild(newNode); } } The solution works for me and if it is an ok solution please use it. If not? Throw it away and solve the bug anyway you like. / Erik Rydgren
