XSLT 2.0 / Java: System Bell

2019-09-05 18:01发布

问题:

I multi-task while I run transforms. I would like some template matches and fallbacks to ring the system bell to catch my attention.

Attempt 1: a java call to ring the system bell, but have been unable to make it work (my java knowledge is limited).

As a starting point, I tried to alter this template which is a working 4 second sleep implementation in the OxygenXML environment with Saxon PE. No success.

 <xsl:template name="sleep" xmlns:thread="java.lang.Thread">
    <xsl:value-of select="thread:sleep(4000)"/>        
</xsl:template>

Attempt 2: I tried various <xsl:message select="'asci bell foo'"/> to try and ring a system bell. No luck.

Amplifying info: I'm using an up to date Linux Mint (an Ubuntu variant).

What can I do to ring the system bell in a transform? Most likely in the form of a call template.

回答1:

I tried the following approach on Windows 10 with Saxon 9.6 and 9.7 PE from the command line, both in a normal command prompt as well as in a PowerShell window:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:sys="java:java.lang.System"
  xmlns:ps="java:java.io.PrintStream"
  exclude-result-prefixes="xs sys ps"
  version="2.0">

<xsl:template name="bell">
  <xsl:variable name="serr" select="sys:err()"/>
  <xsl:value-of select="ps:write($serr, 7)"/>
</xsl:template>

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="foo">
  <xsl:call-template name="bell"/>
  <bar>
    <xsl:apply-templates/>
  </bar>
</xsl:template>

</xsl:stylesheet>

It does give a sound when run against an XML input document having a foo element, but it looks as there is only a single sound produced, even if the template is matched several times.



回答2:

I checked Martin's Q as the answer. He answered the question as it was asked.

However, the system bell was faint, so I ended up going in a different direction when I remembered this Stack Q: Can XSLT execute a shell script at the OS level?. Demo:

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:os-command="java:java.lang.Runtime"
exclude-result-prefixes="xs os-command"
version="2.0">

<xsl:template match="/">        
    <xsl:call-template name="tone"/>         
</xsl:template>

<xsl:template name="tone">
  <xsl:value-of 
   select="os-command:exec(os-command:getRuntime(),'aplay /usr/share/sounds/linuxmint-gdm.wav')"/>
</xsl:template>

or

    <xsl:template name="tone"  xmlns:os-command="java.lang.Runtime">
    <xsl:value-of select="os-command:exec(os-command:getRuntime(),'aplay /usr/share/sounds/linuxmint-gdm.wav')"/>
</xsl:template>

It plays a wav file in Linux Mint (not a shell script). The command line could be changed to your situation.

There are probably more efficient ways to do this, but this will probably only fire off one or two times a day.



标签: java xslt