Logging with XSLT

2019-03-15 21:20发布

How and where could I output log messages for debug and performance purposes during an XSLT transformation?

I guess the simplest method is using expressions like this:

<xsl:text>message text</xsl:text>

here and there in the code, using xsl:value-of if needed.

But this method prints the messages in a lot of places in the output file (HTML page in my case), that is where it is called, and not always in the same place (like a log file).

Is this the only way or is there a better solution? Thanks!

标签: xslt logging
6条回答
男人必须洒脱
2楼-- · 2019-03-15 21:29

Modifying your XSLT itself for the purposes of logging is inevitably going to impact on performance, you're probably better off using an external tool. There are a few available depending on what you're working with:

查看更多
Animai°情兽
3楼-- · 2019-03-15 21:36

You should be able to use <xsl:message> I think, although where the logging goes is implementation-dependent.

查看更多
beautiful°
4楼-- · 2019-03-15 21:40

This is exactly what <xsl:message> is designed for. However, the output location is entirely dependent on the processor. I only have a Mac handy but, sadly, both Firefox and Safari suppress the <xsl:message> output. I expect MSIE will do the same.

Given that, I think your best bet is to use <xsl:comment> to generate your logs. Something like the below should do the trick:

<xsl:template match='my-element'>
   <xsl:comment>Entering my-element template</xsl:comment>
   <p class='my-element'><xsl:apply-templates/></p>
   <xsl:comment>Leaving my-element template</xsl:comment>
</xsl:template>

That would give you something like this in the output:

<!-- Entering my-element template -->
<p class='my-element'>...</p>
<!-- Leaving my-element template -->

Clearly, you can put whatever logging you want into that that output. I would consider creating something like the following and using it to run your logging. This references a global param called 'enable-logging' to determine if logging should occur or not.

<xsl:template name='create-log'>
   <xsl:param name='message'/>
   <xsl:if test="$enable-logging = 'yes'">
       <xsl:comment><xsl:value-of select='$message'/></xsl:comment/>
   </xsl:if>
</xsl:template>

Use this in your stylesheet as:

<xsl:template match='my-element'>
   <xsl:call-template name='create-log'>
     <xsl:with-param name='message'/>Entering my-element template</xsl:with-param>
   </xsl:call-template>
   <p class='my-element'><xsl:apply-templates/></p>
   <xsl:call-template name='create-log'>
     <xsl:with-param name='message'/>Leaving my-element template</xsl:with-param>
   </xsl:call-template>
</xsl:template>

One benefit of doing it this way is you can change that <xsl:comment> to <xsl:message> when in a more complete environment. It is more verbose but more general.

查看更多
等我变得足够好
5楼-- · 2019-03-15 21:40

I would suggest using xsl:message if you are in a development environment such as oXygen or Stylus Studio, and using xsl:comment if you are running in the browser. You shouldn't really be debugging your XSLT code in the browser - the browsers I know about are lousy as XSLT debugging tools.

查看更多
戒情不戒烟
6楼-- · 2019-03-15 21:40

By looking for a solution to this problem, I ended up implementing a logging mechanism in XSLT in similar fashion to log4j, using mostly xsl:message and pure XSLT 2.x. I took some of the answers in this page as inputs. The library is available here: https://github.com/ukuko/log4xslt

查看更多
乱世女痞
7楼-- · 2019-03-15 21:48

A simple hack would be to create a variable with xsl:variable and to either just concat() new values to it or to set up a xsl:template which does the same thing. Then you just need to output this variable at the end of the execution and you can explicitly choose where to show the log.

查看更多
登录 后发表回答