Hi all!
> Two unrelated questions. The first is that I would like to transform a
> DOM into a DOM, the reason for this is that there may be a number of
> stylesheets applied to a single input XML document,
One way is to create a document builder (e.g. using
XalanTransformer::createDocumentBuilder()), get its document
(XalanDocumentBuilder::getDocument ()),
feed it into a FormatterToSourceTree and finally create a XSLTResultTarget
with the formatter object. The only dirty hack is casting the XalaDocument*
to
XalanSourceTreeDocument*...
short example (might not compile directly...)
XSLTResultTarget* theTarget = NULL;
XalanDocument* theResultDoc = NULL;
FormatterToSourceTree* theSourceTreeFormatter = NULL;
XalanDocumentBuilder* theDocumentBuilder = NULL;
XalanTransformer transformer;
// create document builder
theDocumentBuilder = transformer.createDocumentBuilder();
// get document (which is a XalanDSourceTreeDocument)
theResultDoc = theDocumentBuilder->getDocument();
// create source tree formatter
// this is the only dirty hack: casting the XalaDocument* to
XalanSourceTreeDocument*...
theSourceTreeFormatter = new
FormatterToSourceTree((XalanSourceTreeDocument*) theResultDoc);
// create the result target
theTarget = new XSLTResultTarget(*theSourceTreeFormatter);
// perform transformations
...
// release document builder
transformer.destroyDocumentBuilder(theDocumentBuilder);
// release all other objects
if (theSourceTreeFormatter) {
delete theSourceTreeFormatter;
}
if (theTarget) {
delete theTarget;
}
The document builder can be released right after the transformation,
the target after the following transformation (for which it serves as input)
> The second question is that I have some extension functions that return
> nodesets, containing dynamically generated nodes (these are in fact SQL
> lookups). I do this by creating a XalanSourceTreeDocument and adding
> nodes onto this,
> Now my problem is that this document does not belong to the execution
> context, and in fact here it belongs to nothing (and is leaked). Should I
> just have the function object cache the generated documents, or is there a
> better way of doing this?
My approach was to have a instance of class XalanTransformer as member
variable
of my extension function class. Again I use XalanTransformer to create a
document
builder, get its content handler and use the SAX methods
startDocument()/startElement()/
characters()/endDocument()/endElement() to create my nodes. After calling
endDocument(),
simply get the document node, create a node set as result and append the
document node.
The document is deleted at the end of the life cycle of the extension
function in the
destructor of XalanTransformer. If a instance of XalanTransformer is used
for the
transformation as well, the extension function object will be cloned for
each transformation.
Therefore it is deleted right after the transformation, so the newly created
nodes last
only for this single transformation.
short example (might not compile directly...)
class FunctionCreateNodes : public Function {
// the usual stuff like constructor, destructor and all necessary Function
members
protected:
XalanTransformer m_XmlXsltHelper;
}
XObjectPtr FunctionCreateNodes::execute(
XPathExecutionContext& executionContext,
XalanNode* context,
const XObjectArgVectorType& args,
const Locator* locator) const
{
XObjectPtr theResult;
typedef
XPathExecutionContext::BorrowReturnMutableNodeRefList
BorrowReturnMutableNodeRefList;
BorrowReturnMutableNodeRefList theResultList(executionContext);
AttributesImpl theAttributes;
XalanDOMString theNamespaceName("My/Personal/Namespace);
XalanDOMString thePrefixName("mpn");
XalanDOMString theElementName;
XalanDOMString theAttributeName;
XalanDOMString theAttributeValue;
const XalanDOMString theAttributeType("CDATA");
XalanDOMString theTextValue;
// create document builder
XalanDocumentBuilder* const theDOMBuilder =
m_XmlXsltHelper.createDocumentBuilder();
assert(theDOMBuilder != 0);
// Get the SAX2 ContentHandler from the builder...
ContentHandler* const theContentHandler =
theDOMBuilder->getContentHandler();
assert(theContentHandler != 0);
// start the document
theContentHandler->startDocument();
// create root node
assign(theElementName, XALAN_STATIC_UCODE_STRING("root"));
theAttributes.clear();
// add name attribute
assign(theAttributeName, XalanDOMString("msg"));
assign(theAttributeValue, XalanDOMString("Hello World!"));
theAttributes.addAttribute(c_wstr(theAttributeName),
c_wstr(theAttributeType), c_wstr(theAttributeValue));
// start element
theContentHandler.startElement(c_wstr(theNamespaceName),
c_wstr(theElementName), c_wstr(thePrefixName + theElementName),
theAttributes);
// TODO: add some more nodes
// end element
assign(theElementName, XALAN_STATIC_UCODE_STRING("root"));
theContentHandler.endElement(c_wstr(theNamespaceName),
c_wstr(theElementName), c_wstr(thePrefixName + theElementName));
// end the document
theContentHandler->endDocument();
XalanDocument* pNewDoc = theDOMBuilder->getDocument();
if (pNewDoc) {
// get the created nodes and append it to the result
theResultList->addNodeInDocOrder(pNewDoc, executionContext);
theResult =
executionContext.getXObjectFactory().createNodeSet(theResultList);
}
else {
// empty node set
executionContext.warn(XalanDOMString("no document created"));
theResult =
executionContext.getXObjectFactory().createNodeSet(theResultList);
}
return theResult;
}
Hope that helps
Wolfgang
--
Wolfgang Schell
[EMAIL PROTECTED]
GMX - Die Kommunikationsplattform im Internet.
http://www.gmx.net