tags:

views:

403

answers:

2

Hi,

I am trying to set the width variables <WIDTH> and <WIDTH1> within XSL which I am retriveing from the web.config within c# as below:

string Width1    = System.Configuration.ConfigurationSettings.AppSettings.Get("Width1");
string Width2   = System.Configuration.ConfigurationSettings.AppSettings.Get("Width2");

cslx.Xslt=@"<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'&gt;
 <xsl:output method='html'/>
 <xsl:template match='/'>
  <link rel='stylesheet' type='text/css' href='/StyleSheets/test.css'/>
  <xsl:apply-templates select='/Data/Test/TestItems/TestItem'/>
 </xsl:template>
 <xsl:template match='TestItem'>
    <xsl:when='boolean($Link1Items)or boolean($Link2Items) or boolean($Link3Items)'>
    <table width='<WIDTH1>' class='tablestyle '>
    </xsl:when>
    <xsl:otherwise>
    <table width='<WIDTH2>' class='tablestyle '>
    </xsl:otherwise> 
  </table>
 </xsl:template>
</xsl:stylesheet>
";

//  update subsitution parameters
cslx.Xslt = cslx.Xslt.Replace("<WIDTH1>", Width1);
cslx.Xslt = cslx.Xslt.Replace("<WIDTH2>", Width2);

But the HTML is not generated and an error is thrown regarding the table tag which is not closed.

I know the table tag must go inside each of the xsl:when and xsl:otherwise tags but I want to avoid this.

My problem is there is a lot XSL code between the tags and I want to avoid code duplication! Is there any other way I can acheive this?

Many Thanks,

A: 

Your XSL is not well-formed XML , e.g.:

   <xsl:otherwise>
    <table width='<WIDTH2>' class='tablestyle '>
    </xsl:otherwise> 
  </table>

The first thing you should do is concentrate on getting the XSLT correct. Note that you must have xsd:choice elements wrapping the xsl:otherwise, etc. There are a lot of other errors (e.g. xsl:when=... should be xsl:when test="...). Take it in steps:

  1. learn how to write XML
  2. Learn XSLT
  3. Only then put it into C#
peter.murray.rust
+3  A: 
  1. Use XSLT parameters to pass parameters to your stylesheet, not string replacement.
  2. Your XSLT is not a well formed XML document. To manipulate attributes, you have to use your xsl:whens inside an xsl:attribute element. In your case your code should be like this:


string Width1 = System.Configuration.ConfigurationSettings.AppSettings.Get("Width1");
string Width2 = System.Configuration.ConfigurationSettings.AppSettings.Get("Width2");

cslx.Xslt=@"<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'&gt;
 <xsl:output method='html'/>
 <xsl:param name='width1' />
 <xsl:param name='width2' />
 <xsl:template match='/'>
  <link rel='stylesheet' type='text/css' href='/StyleSheets/test.css'/>
  <xsl:apply-templates select='/Data/Test/TestItems/TestItem'/>
 </xsl:template>
 <xsl:template match='TestItem'>
    <table class='tablestyle'>
      <xsl:attribute name='width'>
        <xsl:choose>
        <xsl:when test='boolean($Link1Items)or boolean($Link2Items) or boolean($Link3Items)'><xsl:value-of select='$width1' /></xsl:when>
        <xsl:otherwise><xsl:value-of select='$width2' /></xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
    </table>
 </xsl:template>
</xsl:stylesheet>
";

var xslt = new XslCompiledTransform();
xslt.Load(new XmlTextReader(new StringReader(cslx.Xslt)));

var args = new XsltArgumentList();
args.AddParam("width1", "", Width1);
args.AddParam("width2", "", Width2);

// whenever you want to transform
var writer = new XmlWriter("output.xml");
xslt.Transform(document, args, writer);
ssg
Note that even this is not well-formed - see xsl:when construct
peter.murray.rust
Yeah I'd copied his when line, fixed it now, thanks.
ssg
The way to address the problem is to use parameters. If you're using XSLT - I'd be much happier with the XSLT in its own file (visual studio lets you debug XSLT transformations of XML).
Murph
thank you for the pointer to using xsl:attribute and xsl:param. One last question is how would i set the html table width attribute to the XSLT width attribute? Something like...? <table width ='<xsl:value-of select="@width"/>'
nav
You do it with the xsl:attribute element. Check out my version of the code. It does the exact thing you want. For details: http://msdn.microsoft.com/en-us/library/ms256165.aspx
ssg
Or you can also use inline attribute syntax (but you can't use xsl:when with that). like: <table width="{$width1}">
ssg
many thanks ssg! [i should have read the definition of xsl:attribute]
nav
Cok tesekkur ederim!
nav