It looks to me as if the output you want to produce is so similar to the output produced by the existing XSLTTraceListener that you should be able to achieve it simply by modifying the XSLTTraceListener class to meet your requirements. If that isn't the case, you should be able to achieve it by also modifying the XSLTTraceCodeInjector, and the TraceExpression that the XSLTTraceCodeInjector inserts into the expression tree (perhaps to add some extra compile-time information into the TraceExpression). None of these classes has any special status in Saxon; they are simply examples of what can be achieved using the interfaces Saxon supplies.

However, I don't think you will be able to understand these classes purely from the documentation in the Javadoc. People building debuggers for Saxon typically have to study the source code and acquire a fairly detailed understanding of how it works.

Michael Kay
Saxonica

On 09/08/2012 17:15, Paul Ryan wrote:
Michael,

Ok that clarifies a few things. I'm not just trying to wrap at the outer most level I'm trying to inject trace information at every level of the output from the XSLT. The general idea is to complete a debugging tool which tells the developer which template led to a given section of output within the output XML/HTML. 

I guess the point that is still confusing after this is how I would go about reconstructing the result in an expression "or constructing a new expression (which will typically produce the same result as the original, but perhaps with side-effects like outputting trace information or checking for a debugging breakpoint)". Is there a piece of code I can use as an example, or a description out how the expression types interact with each other?

So for example lets say as I'm moving through the system I have a document like

<document id="1">
<element>some text</element>
<document>

and I'm using just an identity template.
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="*|@*"/>
</xsl:copy>
</xsl:template>

 My goal is to inject information at each template run into the output of the xslt template expression such that the output document might look something like 

<document xmlns:trace="tracenamespace" id="1">
<trace:enter>
<trace:path>/document[1]</trace:path>
<trace:template>
<trace:firstline>&lt;xsl:template match="node()"&gt;</trace:firstline>
<trace:linenumber>55</trace:linenumber>
</trace:template>
<trace:templatelocation>/path/to/templatefile</trace:templatelocation>
<trace:enter>
<trace:enterattr>
<trace:path>/document[1]/@id</trace:path>
<trace:template>
<trace:firstline>&lt;xsl:template match="node()"&gt;</trace:firstline>
<trace:linenumber>55</trace:linenumber>
</trace:template>
<trace:templatelocation>/path/to/templatefile</trace:templatelocation>
<trace:enterattr>
<element>
<trace:enter>
<trace:path>/document[1]/element[1]</trace:path>
<trace:template>
<trace:firstline>&lt;xsl:template match="node()"&gt;</trace:firstline>
<trace:linenumber>55</trace:linenumber>
</trace:template>
<trace:templatelocation>/path/to/templatefile</trace:templatelocation>
<trace:enter>
some text
</element>
</document>

I have and am already displaying to the users all the information that is in these trace:enter elements so I'm not worried about obtaining the information (I showed you this at balisage last year) the remaining problem is that it is not associated with the output so the developer must try to figure out which one of and ordered set would have called each logged trace statement.

Does this clarify my objectives? Does your recommendation of my creating my own CodeInjector still stand with this clarification?

Again thank you much for the help,

-- Paul Ryan

On Aug 9, 2012, at 11:29 AM, Michael Kay wrote:


The idea of the CodeInjector interface is that you supply a CodeInjector, and the XPath parser calls the inject() method to process each expression on the expression tree; your CodeInjector then has the option of returning the original expression unchanged, or constructing a new expression (which will typically produce the same result as the original, but perhaps with side-effects like outputting trace information or checking for a debugging breakpoint). You should not be calling the inject() method yourself from the application level.

There isn't any direct way of supplying a CodeInjector when you are using the JAXP XPath interface (or, for that matter, when using the s9api interface). I think the only way to do it is to call the static method ExpressionTool.make(), which is a rather low-level interface.

The XSLTTraceCodeInjector isn't much use to you because it only injects code at the level of XSLT instructions, not within an XPath expression. Using the class TraceCodeInjector would make more sense; but I suspect a better approach would be write your own implementation of CodeInjector (you could use TraceCodeInjector as a model).

If you only want to wrap the parsed expression by some construct of your own at the outermost level, then you don't need the code injector at all. You could simply wrap the Expression returned by the XPath parser inside a TraceExpression.

Michael Kay
Saxonica




------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/


_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
saxon-help@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/saxon-help