You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by bu...@apache.org on 2004/01/23 13:24:20 UTC
DO NOT REPLY [Bug 26374] New: -
Transformation ignores xsl:output doctype declaration when transforming to DOM tree
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: xalan-dev@xml.apache.org
ReportedBy: erik.rydgren@mandarinen.se
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