Pergunta

Does anybody know of a preprocessor for XSLT to make it less verbose? Something like what SASS is to CSS, a little proggy that will take light syntax:

"/":
{
 <html>
  <head>
  <title>My book collection</title>
  </head>
  <body>
  {@ "//media"}
  {@ quantity = calc_abs_value("//total_quantity")}
  Price : {@ multiply(price:"//item[@selected='true'][@price]",qty  :$quantity) }
  </body>  
 </html>
}

"media[@type='book']":
{
 <div id="{@id}">
 {title} by {author} published in {published_date}
 </div>
}

function calc_abs_value(value)
{
 if ($value < 0) {- $value} else {$value}
}

function multiply(price,qty:"1")
{
 switch 
 {
  "$qty = 1" : $price * $qty 
  "$qty < 5" : $price * $qty * 0.95 
  "$price * $qty < 0" : 0
  default : 0
 }
}

and turn this into far-less readable XSLT:

    <xsl:template match="/">
     <html>
      <head>
      <title>My book collection</title>
      </head>
      <body>
      <xsl:apply-templates select="//media" />
      <xsl:variable name="quantity"><xsl:call-template name="calc_abs_value">
      <xsl:with-param name="value"><xsl:value-of select="//total_quantity" /></xsl:with-param>
      </xsl:call-template></xsl:variable>
      Price : <xsl:call-template name="multiply">
      <xsl:with-param name="price"><xsl:value-of select="//item[@selected='true'][@price]" /></xsl:with-param>
      <xsl:with-param name="qty"><xsl:value-of select="$quantity" /></xsl:with-param>
      </xsl:call-template>
      </body>  
     </html>
    </xsl:template>


    <xsl:template match="media[@type='book']">
    {
     <div id="{@id}">
     <xsl:value-of select="title" /> by <xsl:value-of select="author" /> published in <xsl:value-of select="published_date" />
     </div>
    }
    </xsl:template>


    <xsl:template name="calc_abs_value">
    <xsl:param name="value" />
    <xsl:choose>
      <xsl:when test="$value < 0">
       - <xsl:value-of select="$value" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$value" />
      </xsl:otherwise>
    </xsl:choose>
    </xsl:template>

I am too lazy to write the XSLT form of multiply but I'm sure you already figured out what I mean.

Or is there an IDE that is more XSLT aware than others, e.g it displays {author} but expands to:

<xsl:value-of select="author" />

when you click it?

Foi útil?

Solução

You should be better ask: how to DSL the XSLT?

You might be interested in some practical example such as YSLT based on YML concept.

NOTE It should be better not to convert/preprocess the code to get an XSLT transform at all; instead, just emulate the way a processor parses the input document and use your own DSL.


You can also write your own DSL. You should use some scripting language which really makes DSL concept easy, as, for example, ruby. In ruby, you can achieve something very nice and clean like:

match "/" do
 value-of :foo
end

which could work as:

<xsl:template match="/">
 <xsl:value-of select="foo"/>
</xsl:template>

Another thing that worth to be mentioned is templating languages like erb. This is I think the only feasible alternative to XSLT in general (even if alternative here is a big compromise and you get lost very soon with procedural manipulation of nodes).


Note

I love XSLT verbosity and, because of this verbosity, I think XSLT code is much more readable then any other language (once you understand how templates work).

I don't recommend to search something for converting some different markup to XSLT code. Your final XSLT code will loose of readbility and its code will not be optimal at all.

Outras dicas

I've seen a few attempts to do this over the years but none that seems to have been used by anyone other than its originator. I think, frankly, the verbosity of XSLT is something you quickly get used to. XSLT 2.0 is of course far less verbose than 1.0.

At Balisage last week Evan Lenz presented yet another attempt, called Carrot: this time not just a compact syntax for XSLT but a language that attempts to provide the union of XSLT and XQuery. Looks interesting, but I don't think there's an implementation yet (and I'd be surprised if it catches on...)

Processing-instructions can be used to implement macros, such as in this unrelated question on Docbook.

Template:
<?echo gal?>

Code:
<xsl:variable name="gal" select="'howdy'"/>

<xsl:template match="processing-instruction('echo')">
  <xsl:value-of select="//xsl:variable/@select[../@name=current()]"/>
</xsl:template>

There's also a similar question which covers simplified parameter passing.

XMLPreprocess or oXML may also be of interest as well.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top