views:

139

answers:

3

I'm trying to generate some C# code using xslt - its working great until I get to generics and need to output some text like this:

MyClass<Type>

In this case I've found that the only way to emit this is to do the following:

MyClass<xsl:text disable-output-escaping="yes">&lt;</xsl:text>Type<xsl:text disable-output-escaping="yes">&gt;</xsl:text>

Where:

  • Often it all needs to go on one line, otherwise you end up with line breaks in the generated code
  • In the above example I technically could have used only 1 <xsl:text />, however usually the type Type is given by some other template, e.g:

<xsl:value-of select="@type" />

I don't mind having to write &lt; a lot, but I would like to avoid writing <xsl:text disable-output-escaping="yes">&lt;</xsl:text> for just a single character!

Is there any way of doing disable-output-escaping="yes" for the entire document?

A: 

I know this is NOT a direct answer of your question but.

Huge assumption here: you have somthing like:

<classthing class="MyClass" type="atype"/>

You could call a template:

 <xsl:template match="classthing">
    <xsl:call-template name="setgeneric">
      <xsl:with-param name="myclass"><xsl:value-of select="@class" /></xsl:with-param>
      <xsl:with-param name="mytype"><xsl:value-of select="@type" /></xsl:with-param>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="setgeneric">
    <xsl:param name="myclass" />
    <xsl:param name="mytype" />
    <xsl:value-of select="$myclass"/>
    <xsl:text disable-output-escaping="yes">&lt;</xsl:text>
    <xsl:value-of select="$mytype"/>
    <xsl:text disable-output-escaping="yes">&gt;</xsl:text>
  </xsl:template>
Mark Schultheiss
+1  A: 

its working great until I get to generics and need to output some text like this:

MyClass<Type>

In this case I've found that the only way to emit this is to do the following:

MyClass<xsl:text disable-output-escaping="yes">&lt;</xsl:text>Type<xsl:text

disable-output-escaping="yes">>

Certainly, this is not the only way and this is the worst way to produce such result.

Is there any way of doing disable-output-escaping="yes" for the entire document?

This is what the method="text" attribute of <xsl:output> is for. No need of DOE.

So, use the text output method and then:

 MyClass&lt;Type>

Here is a complete small example.

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <xsl:output method="text"/>

 <xsl:template match="/">
  MyClass&lt;Type>
 </xsl:template>
</xsl:stylesheet>

When the above transformation is applied on any XML document (not used), the wanted result is produced:

  MyClass<Type>

I am the author of the XPath Visualizer, which produces IE-like presentation of XML files -- nowhere in thie code there is any DOE.

Dimitre Novatchev
I already have `<xsl:output method="text" />` in my XSLT, but it makes no difference - is it possible I'm calling my XSLT processor incorrectly?
Kragen
@Kragen: I updated the answer to give you a complete example how to generate the desired text without DOE.
Dimitre Novatchev
Thanks - I have no idea why I thought it wasn't working, but this seems to work for me now.
Kragen
Ah! Just figured out why this wasn't working! - See my answer
Kragen
A: 

The reason why this wasn't working was all down to the I was applying the transform - I was using a XslCompiledTransform and an XmlWriter to transform my xml, however according to Microsoft XML Teams blog as soon as I use an XmlWriter to write my output the tag is ignored!

I fixed this by explicitly setting the XmlWriters output settings to those of the Xsl transform:

XmlWriterSettings ws = xslt.OutputSettings.Clone();
ws.CheckCharacters = false;

xslt.Transform("MyDocument.xml", XmlWriter.Create(Console.Out, ws));

Once I did this, the transform respected my tag, and all was well!

Kragen