Solved

Why won't this XSLTransform work?!

Posted on 2004-10-30
241 Views
Last Modified: 2008-02-01
Hello,

I am using the following code to 1) Load an XML file from a URL, 2) Load an XSL file from a URL and (the problem part), 3) Transform the XML file with the given XSL file and then ADD the resulting controls generated to the page.

Here's all my code:

SOURCE XML FILE
============
<ELEMENTS>
      <ELEMENT NAME="HEADING" TYPE="TEXT" MAXLENGTH="255" REQUIRED="YES" MULTILINE="FALSE" DESCRIPTION="This is the title of your document."></ELEMENT>
      <ELEMENT NAME="BYLINE" TYPE="TEXT" MAXLENGTH="255" REQUIRED="YES" MULTILINE="FALSE" DESCRIPTION="This is a short description of what your document is about."></ELEMENT>
      <ELEMENT NAME="BODY" TYPE="TEXT" MAXLENGTH="-1" REQUIRED="YES" MULTILINE="TRUE" DESCRIPTION="This is where you type the main content of your document."></ELEMENT>
      <ELEMENT NAME="RELATED" TYPE="TEXT" MAXLENGTH="-1" REQUIRED="YES" MULTILINE="TRUE" DESCRIPTION="This is where you can specify related documents."></ELEMENT>
</ELEMENTS>
======================

SOURCE XSLT FILE:
======================
<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:asp="remove">
    <xsl:output method="xml" indent="yes" encoding="utf-8" omit-xml-declaration="yes"/>
    <xsl:template match="/">
        <table>
        <xsl:for-each select="//element">
            <tr>
            <td valign="top"><xsl:value-of select="@name" />
            <xsl:if test="@required = 'yes'">
                    <asp:RequiredFieldValidator ErrorMessage="Cannot leave blank" runat="server" ControlToValidate="{@name}" />
            </xsl:if>
            </td>
            <td>
            <xsl:if test="@type='text'">
                <asp:TextBox id="{@name}" runat="server" />
            </xsl:if>
            <xsl:if test="@type='radio'">
                <asp:RadioButtonList id="{@name}" runat="server">
                    <xsl:for-each select="choice">
                           <asp:ListItem Value="{@value}">
                                 <xsl:value-of select="@value"/>
                       </asp:ListItem>
                    </xsl:for-each>
                </asp:RadioButtonList>
            </xsl:if>
            </td></tr>
        </xsl:for-each>
        </table>
            <asp:button id="submit" runat="server" Text="Submit" />
    </xsl:template>
</xsl:stylesheet>
===============================================

NOW -- I'm trying to convert the sample found on http://www.dnzone.com/showDetail.asp?TypeId=2&NewsId=151&LinkFile=page3.htm into VB.NET, and am having no luck. I keep getting all sorts of errors when calling the objTransform.Transform() method in the following code in my Page_Init() handler:

     
Dim TemplateDoc As New XPath.XPathDocument(System.Configuration.ConfigurationSettings.AppSettings("Base_URL") & System.Configuration.ConfigurationSettings.AppSettings("Public_FolderName") & "/iPublish/Templates/" & Request("Template") & ".xml")

        Dim objTransform As New XslTransform
        objTransform.Load(System.Configuration.ConfigurationSettings.AppSettings("Base_URL") & System.Configuration.ConfigurationSettings.AppSettings("Public_FolderName") & "/iPublish/Templates/" & Request("Template") & ".xslt")

        Dim SW As New StringWriter
        Dim Args As System.Xml.Xsl.XsltArgumentList()
        Dim Result As String

        Result = SW.ToString

        Dim CTRL As Control
        CTRL = Page.ParseControl(result)
        Page.Controls.Add(CTRL)

        InitializeComponent()

------- And it doesn't work!

Any one shed any light? It's certainly a bit of a challenge!!! :)

Thanks

 
0
Question by:OnError_Fix
    9 Comments
     
    LVL 25

    Expert Comment

    by:nauman_ahmed
    Following is an example from MSDN:

    The following code example loads an XSL style sheet, reads a file called mydata.xml into an XPathDocument, and performs a transformation on the data on a fictitious file called myStyleSheet.xsl, sending the formatted output to the console.
    [Visual Basic]
    Imports System
    Imports System.IO
    Imports System.Xml
    Imports System.Xml.XPath
    Imports System.Xml.Xsl

    Public Class Sample
        Private filename As [String] = "mydata.xml"
        Private stylesheet As [String] = "myStyleSheet.xsl"

        Public Shared Sub Main()
            Dim xslt As New XslTransform()
            xslt.Load(stylesheet)
            Dim xpathdocument As New XPathDocument(filename)
            Dim writer As New XmlTextWriter(Console.Out)
            writer.Formatting = Formatting.Indented

            xslt.Transform(xpathdocument, Nothing, writer, Nothing)
        End Sub 'Main
    End Class 'Sample


    HTH, Nauman.
    0
     
    LVL 28

    Expert Comment

    by:mmarinov
    Hi OnError_Fix,

    the problem that it is not work is that you have never transform the xml with the xslt
    you have missed that line

    objTransform.Transform(TemplateDoc, Nothing, SW, Nothing)

    before

    Result = SW.ToString

    Regards!
    B..M
    0
     

    Author Comment

    by:OnError_Fix
    B..M...

    The code below produces the following error:

    An error was encountered on page /resources/iPublish/Publish_TemplateSelected.aspx.
    The error was: System.Web.HttpParseException: Parser Error: The server tag is not well formed. ---> System.Web.HttpException: The server tag is not well formed.
       at System.Web.UI.TemplateParser.DetectSpecialServerTagError(String text, Int32 textPos)
       at System.Web.UI.TemplateParser.ParseStringInternal(String text)
       at System.Web.UI.TemplateParser.ParseString(String text, String virtualPath, String basePhysicalDir)
       --- End of inner exception stack trace ---
       at System.Web.UI.TemplateParser.ParseString(String text, String virtualPath, String basePhysicalDir)
       at System.Web.UI.TemplateParser.Parse()
       at System.Web.UI.TemplateParser.ParseTemplateInternal(String content, HttpContext context, String baseVirtualDir)
       at System.Web.UI.TemplateControl.ParseControl(String content)
       at Incorpex.Olympia2004V1.Publish_TemplateSelected.Page_Init(Object sender, EventArgs e) in C:\Documents and Settings\r.parker\VSWebCache\intranet.domain.net\resources\ipublish\Publish_TemplateSelected.aspx.vb:line 69
       at System.Web.UI.Control.OnInit(EventArgs e)
       at System.Web.UI.Control.InitRecursive(Control namingContainer)
       at System.Web.UI.Page.ProcessRequestMain()
       at System.Web.UI.Page.ProcessRequest()
       at System.Web.UI.Page.ProcessRequest(HttpContext context)
       at System.Web.CallHandlerExecutionStep.System.Web.HttpApplication+IExecutionStep.Execute()
       at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

    Source: System.Web / System.Web
    -------------------------

    Here's the code (LINE 69 Is highlighted with ****):

     ' Load our XML file into the XmlDocument object.
            Dim myXmlDoc As XmlDocument = New XmlDocument
            myXmlDoc.Load(System.Configuration.ConfigurationSettings.AppSettings("Base_URL") & System.Configuration.ConfigurationSettings.AppSettings("Public_FolderName") & "/iPublish/Templates/" & Request("Template") & ".xml")

            ' Load our XSL file into the XslTransform object.
            Dim myXslDoc As Xsl.XslTransform = New Xsl.XslTransform
            myXslDoc.Load(System.Configuration.ConfigurationSettings.AppSettings("Base_URL") & System.Configuration.ConfigurationSettings.AppSettings("Public_FolderName") & "/iPublish/Templates/" & Request("Template") & ".xslt")

            Dim myStringBuilder As System.Text.StringBuilder = New System.Text.StringBuilder
            Dim myStringWriter As StringWriter = New StringWriter(myStringBuilder)

            myXslDoc.Transform(myXmlDoc, Nothing, myStringWriter, Nothing)
           
           ************** Page.Controls.Add(Page.ParseControl(myStringBuilder.ToString))    ************

            InitializeComponent()

    ---- Cheers

    0
     
    LVL 28

    Expert Comment

    by:mmarinov
    hi  there,

    i've got a working solution with an exception : the button can not be rendered ( unfortunately i can not say why :( ) i've tested it a lot of times but the xmlns:asp="remove" has been added to the asp:button tag but it can not be added for example to the asp:RequiredFieldValidator

    the working code is ( just replace your paths )

    mlDocument myXmlDoc = new XmlDocument();
                      myXmlDoc.Load("http://localhost/csharp_web/XMLFile1.xml");



            // Load our XSL file into the XslTransform object.
            System.Xml.Xsl.XslTransform myXslDoc = new System.Xml.Xsl.XslTransform();
            myXslDoc.Load("http://localhost/csharp_web/XSLTFile1.xslt");

                System.Text.StringBuilder myStringBuilder = new System.Text.StringBuilder();
                System.IO.StringWriter myStringWriter = new System.IO.StringWriter(myStringBuilder);

            myXslDoc.Transform(myXmlDoc, null, myStringWriter, null);
           
            Panel1.Controls.Add(Page.ParseControl(myStringBuilder.ToString()));
            InitializeComponent();

    also you have to be care when you use XSLT and XML because the XML is case sensitive
    so your xslt about the posted XML must be:
    <?xml version="1.0" encoding="UTF-8" ?>
    <xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:asp="http://www.w3.org/1999/">
        <xsl:output method="xml" indent="yes" encoding="utf-8" omit-xml-declaration="yes"/>
        <xsl:template match="/">
            <table>
            <xsl:for-each select="//ELEMENT">
                <tr>
                <td valign="top"><xsl:value-of select="@NAME" />
                <xsl:if test="@REQUIRED = 'YES'">
                       <asp:RequiredFieldValidator ErrorMessage="Cannot leave blank" runat="server" ControlToValidate="{@NAME}" />
                </xsl:if>
                </td>
                <td>
                <xsl:if test="@TYPE='TEXT'">
                    <asp:TextBox id="{@NAME}" runat="server" />
                </xsl:if>
                <xsl:if test="@TYPE='RADIO'">
                    <asp:RadioButtonList id="@NAME" runat="server">
                        <xsl:for-each select="choice">
                             <asp:ListItem Value="@VALUE">
                                  <xsl:value-of select="@VALUE"/>
                           </asp:ListItem>
                        </xsl:for-each>
                    </asp:RadioButtonList>
                </xsl:if>
                </td></tr>
            </xsl:for-each>
            </table>
            <asp:Button id="btn" runat="server"></asp:Button>
               
        </xsl:template>
    </xsl:stylesheet>

      B..M
    0
     

    Author Comment

    by:OnError_Fix
    Ok, B..M... Still one problem!

    I am getting "The Server Tag is Not Well Formed" as the error message when running the page.

    Here's all the code so you can see exactly what I've got:

    --------------- DATA.XML ------------------
    <ELEMENTS>
          <ELEMENT NAME="HEADING" TYPE="TEXT" MAXLENGTH="255" REQUIRED="YES" MULTILINE="FALSE" DESCRIPTION="This is the title of your document."></ELEMENT>
          <ELEMENT NAME="BYLINE" TYPE="TEXT" MAXLENGTH="255" REQUIRED="YES" MULTILINE="FALSE" DESCRIPTION="This is a short description of what your document is about."></ELEMENT>
          <ELEMENT NAME="BODY" TYPE="TEXT" MAXLENGTH="-1" REQUIRED="YES" MULTILINE="TRUE" DESCRIPTION="This is where you type the main content of your document."></ELEMENT>
          <ELEMENT NAME="RELATED" TYPE="TEXT" MAXLENGTH="-1" REQUIRED="YES" MULTILINE="TRUE" DESCRIPTION="This is where you can specify related documents."></ELEMENT>
    </ELEMENTS>

    -----------------------------------------------

    And......

    --------------- DATA.XSLT -----------------
    <xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:asp="remove">
        <xsl:output method="xml" indent="yes" encoding="utf-8" omit-xml-declaration="yes"/>
        <xsl:template match="/">
            <table>
            <xsl:for-each select="//ELEMENT">
                <tr>
                <td valign="top"><xsl:value-of select="@NAME" />
                <xsl:if test="@required = 'YES'">
                        <asp:RequiredFieldValidator ErrorMessage="Cannot leave blank" runat="server" ControlToValidate="{@name}" />
                </xsl:if>
                </td>
                <td>
                <xsl:if test="@type='text'">
                    <asp:TextBox id="{@NAME}" runat="server" />
                </xsl:if>
                <xsl:if test="@type='radio'">
                    <asp:RadioButtonList id="{@NAME}" runat="server">
                        <xsl:for-each select="choice">
                               <asp:ListItem Value="{@VALUE}">
                                     <xsl:value-of select="@VALUE"/>
                           </asp:ListItem>
                        </xsl:for-each>
                    </asp:RadioButtonList>
                </xsl:if>
                </td></tr>
            </xsl:for-each>
            </table>
                <asp:button id="submit" runat="server" Text="Submit" />
        </xsl:template>
    </xsl:stylesheet>

    -----------------------------------------------

    And, finally!......

    --------------- PAGE.ASPX -----------------
    Dim myXmlDoc = New XmlDocument
            myXmlDoc.Load(System.Configuration.ConfigurationSettings.AppSettings("Base_URL") & System.Configuration.ConfigurationSettings.AppSettings("Public_FolderName") & "/iPublish/Templates/" & Request("Template") & ".xml")

            Dim myXslDoc As New System.Xml.Xsl.XslTransform
            myXslDoc.Load(System.Configuration.ConfigurationSettings.AppSettings("Base_URL") & System.Configuration.ConfigurationSettings.AppSettings("Public_FolderName") & "/iPublish/Templates/" & Request("Template") & ".xslt")

            Dim myStringBuilder As New System.Text.StringBuilder
            Dim myStringWriter As New System.IO.StringWriter(myStringBuilder)

            myXslDoc.Transform(myXmlDoc, Nothing, myStringWriter, Nothing)

            frmTemplate.Controls.Add(Page.ParseControl(myStringBuilder.ToString()))

            InitializeComponent()

    -----------------------------------------------

    Everybody -- please note, I am doing this in VB.NET, not C#!!

    B...M I converted your C# code into the version shown above. That seems to work fine (no compile errors this time), but note I am adding the outputted controls to a FORM tag, frmTemplate, as I've shown.

    If the XSLT file has the following "<xml version="1.0" encoding="UTF-8"?>" tag at the top, then the error message shown becomes:
    ************************
    The error was: System.Web.HttpUnhandledException: Exception of type System.Web.HttpUnhandledException was thrown. ---> System.Xml.XmlException: This is an unexpected token. The expected token is 'NAME'. Line 1, position 38.
    ************************

    If I take that line out, I get:
    ************************
    The error was: System.Web.HttpParseException: Parser Error: The server tag is not well formed. ---> System.Web.HttpException: The server tag is not well formed.
    *************************

    Back to the drawing board!!

    Cheers,

    OnError_Fix
    0
     

    Author Comment

    by:OnError_Fix
    P.S. Increased the point value
    0
     
    LVL 28

    Accepted Solution

    by:
    first of all
    <xml version="1.0" encoding="UTF-8"?>
    must be
    <?xml version="1.0" encoding="UTF-8"?>

    second , as i've posted - i don't know why but the <asp:Button tag rises this exception
    remove the line

    <asp:button id="submit" runat="server" Text="Submit" />

    and everything will be ok
    sorry for the c# code

    B..M
    0
     

    Author Comment

    by:OnError_Fix
    Progress, at last!

    BUT! This time, while no errors are generated, it only prints the words:

    HEADING  
    BYLINE  
    BODY  
    RELATED

    ... on the screen. They should be text boxes, or select boxes.... why not?!

    Thanks,

    Richard.
    0
     

    Author Comment

    by:OnError_Fix
    Hold the train.... by gum with B..M's help I think i've cracked it.

    Finally, it was due to the case sensitivity. Since my source XML is all in upper case, I had to modify the XSL to uppercase too. Then it worked brilliantly. B..M --- you're a diamond!

    Thank you so much.

    Enjoy your points.
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How to run any project with ease

    Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
    - Combine task lists, docs, spreadsheets, and chat in one
    - View and edit from mobile/offline
    - Cut down on emails

    In an ASP.NET application, I faced some technical problems. In this article, I list them out and show the solutions that I found.  I hope it will be useful. Problem: After closing a pop-up window, the parent page should be refreshed automaticall…
    ASP.Net to Oracle Connectivity Recently I had to develop an ASP.NET application connecting to an Oracle database.As I am doing it first time ,I had to solve several problems. This article will help to such developers  to develop an ASP.NET client…
    This video Micro Tutorial is the second in a two-part series that shows how to create and use custom scanning profiles in Nuance's PaperPort 14.5 (http://www.experts-exchange.com/articles/17490/). But the ability to create custom scanning profiles a…
    This video is in connection to the article "The case of a missing mobile phone (https://www.experts-exchange.com/articles/28474/The-Case-of-a-Missing-Mobile-Phone.html)". It will help one to understand clearly the steps to track a lost android phone.

    884 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    20 Experts available now in Live!

    Get 1:1 Help Now