views:

783

answers:

3

I frequently use HTML output in applications, up to now I've used some simple routines to build an HTML string. I want to try something different now:

I want to serialize the data to XML, and provide some XSLT templates to generate the HTML for the webbrowser control. I get that to work statically (slowly digging through writing XSL), but I'd need to change some attributes of the XSL document on the fly: filters, paths etc. to follow the current UI selection.

The data is small enough that the XML serialization on change should not be a problem. I'd like to use "static" external XSL files (so that the user can customize the output to a certain extent), but adjust .

My questions:

Is this idea technically sound?
Can I feed a web browser control dynamically with XML and an XSL document? Can I modify selected path elements and attributes in the XSL on the fly (i.e. without generating a new file)? How to do that in a web browser control? (some pointers to get me started would be nice..)

[edit]Thanks folks, it's working :D[/edit]

+1  A: 

I don't know how your application looks like, so I wouldn't say whether it is a good or bad idea.

Regarding your other questions:

You can transform data in memory and load it into web-browser control. Otherwise you need to save data to temporary files.

You can make choices at runtime with XSLT parameters

aku
+3  A: 

XslCompiledTransform supports parameters, and also extension objects (both via XsltArgumentList. For anything simple, try to use a parameter; extension objects allow much richer funtionality (up to your imagination), but are not as portable to other xslt vendors. A third option is an external file for options, loaded into a variable with xsl:document.

Of course, if you are feeling brave, you can use xslt to write an xslt dynamically - not trivial, though.

In most non-trivial cases, it is simplest to use WebBrowser against a flat file (in the %tmp% area, or against a local web-server (such as HttpListener); changing the html directly tends to leave the control slightly confused re the effective security context.

Marc Gravell
+5  A: 

Usually the way to go is to provide parameters to the transform at runtime and writing the transform so that its behavior is controlled by the parameters.

Usually when I do this, I only pass in one parameter - an XML document - and make the templates query it to determine what they should do. So you'll see stuff like:

<xsl:template match="*">
   <xsl:variable name="cfg" select="$config/*[name() = current()]"/>
   <xsl:choose>
      <xsl:when test="cfg/elementType = 'option'">
         <xsl:apply-templates select="." mode="option">
      <xsl:when test="cfg/elementType = 'optgroup'">
         <xsl:apply-templates select="." mode="optgroup">
      <xsl:when test="cfg/elementType = 'a'">
         <xsl:apply-templates select="." mode="a">

and so on.

It's very straightforward to feed a WebBrowser control dynamically with XML/XSLT:

using (XmlWriter xw = XmlWriter.Create(new StringWriter(output)))
{
    StringBuilder output = new StringBuilder();
    XsltArgumentList args = new XsltArgumentList();
    args.AddParam("config", myConfigXml);
    myXslt.Transform(myXml, args, xw);
    xw.Flush();
    myWebBrowser.DocumentText = output.ToString();
}

If the UI that the user is updating is in the WebBrowser itself (that is, the HTML page contains HTML UI controls), you should be using dynamic HTML techniques, the same way you would if the page was being displayed in a normal browser. That's a whole different bag of bananas.

Robert Rossney