I cannot combine XSLT instructions with actual XML output during tracing. The XML output is "too late".
I am trying to combine the output of an XSLT transformation during tracing with the actual XSLT instructions.
I have implemented a TraceListener and a Writer.
However, the output XML that is send to the Writer is always "too late".
In this example, TraceListener's enter() is called with a NamespaceConstructor, but no namespace is actually written to the XML output at that moment. The namespace is written later during FixedElement.
Am I doing something wrong?
... enter instruction 21:34 net.sf.saxon.expr.instruct.ForEach 2:54 enter instruction 22:52 net.sf.saxon.expr.instruct.NamespaceConstructor 3:45 << **NamespaceConstructor** leave instruction 22:52 net.sf.saxon.expr.instruct.NamespaceConstructor ... enter instruction 102:69 net.sf.saxon.expr.instruct.FixedElement 5:107 [<?xml version="] [1.0] [" ] [encoding="] [UTF-8] ["] [?>] [ ] [<] [xsl:stylesheet] [ ] [xmlns:pre] [=] ["] [http://www.ibm.com] << **Actual namespace in the XML output** . ["] [
Updated by Michael Kay 5 months ago
Yes, this is quite challenging to achieve. There's some buffering of events at various stages in the pipeline, even if no variables are involved.
Most of the buffering occurs in the ComplexContentOutputter which receives the start element event, attribute, and namespace events individually, assembles them, and then issues a single start element event with all the attributes and namespaces when the first child node or end element event is received.
The most obvious reason for this buffering is the XSLT rule that if two attributes with the same name are written, the last one wins. There are other reasons as well, for example choosing a namespace prefix for the element name may depend on what namespace nodes are written.
To resynchronise the events, you might want to make use of the location information passed down the pipeline. It's not easy, but I think this is what the debuggers in products like Oxygen do.
Updated by Gerben Abbink 4 months ago
I have found a solution.
I store TraceListener's enter()/leave() events (XSLT instructions and XML input) in an array and parse Writer's write() for typical XML tokens such as "<", "</", etc. When I find a token I add it to the array. In the end I have an array filled XSLT instructions, XML input and XML output, just what I wanted.
Please register to edit this issue