Home All Groups Group Topic Archive Search About

dotNet XSLT Transformation

Author
8 Nov 2007 4:41 PM
Kris
I'm running into an issue that I need some help with. It seems that
the IE6 XSLT Transformations work slightly differently than when
transformation is done using XslCompiledTransform.

Lets say I have an XML document formatted as follows

<systems>
   <system>
      <administrator>John Doe</administrator>
   </system>
</systems>

And xslt as follows:

<xsl:template match="/">
   <h1>Hello World</h1>
   <xsl:apply-templates select="/systems/system">
</xsl:template>

<xsl:template match="/systems/system">
   <b><xsl:value-of select="administrator"></b>
</xsl:template>

If I transform the document directly by calling the XSLT file from
within the XML document, I see:
<h1>Hello World</h1><b>John Doe</b>

However, if I use the XslCompiledTransform.Transform() method, I see:
<b>John Doe</b>

I guess this method is technically working correctly as it matches the
pattern of the XML document, but it's a tad frustrating as I have code
I need to drop in at the root of the document before that section gets
transformed.  Any ideas on a workaround?

Author
8 Nov 2007 4:57 PM
Martin Honnen
Kris wrote:

Show quote
> And xslt as follows:
>
> <xsl:template match="/">
>    <h1>Hello World</h1>
>    <xsl:apply-templates select="/systems/system">
> </xsl:template>
>
> <xsl:template match="/systems/system">
>    <b><xsl:value-of select="administrator"></b>
> </xsl:template>
>
> If I transform the document directly by calling the XSLT file from
> within the XML document, I see:
> <h1>Hello World</h1><b>John Doe</b>
>
> However, if I use the XslCompiledTransform.Transform() method, I see:
> <b>John Doe</b>
>
> I guess this method is technically working correctly as it matches the
> pattern of the XML document, but it's a tad frustrating as I have code
> I need to drop in at the root of the document before that section gets
> transformed.  Any ideas on a workaround?

Does it improve things when you use

<xsl:template match="/">
    <h1>Hello World</h1>
    <xsl:apply-templates select="systems/system">
</xsl:template>

<xsl:template match="systems/system">
    <b><xsl:value-of select="administrator"></b>
</xsl:template>

?

Putting in a root element might also be a good idea e.g. assuming you
want to create a snippet of HTML then a div container makes sense:

<xsl:output method="html"/>

<xsl:template match="/">
  <div>
    <h1>Hello World</h1>
    <xsl:apply-templates select="systems/system">
  </div>
</xsl:template>

<xsl:template match="systems/system">
    <b><xsl:value-of select="administrator"></b>
</xsl:template>

--

    Martin Honnen --- MVP XML
    http://JavaScript.FAQTs.com/
Author
8 Nov 2007 5:08 PM
Kris
On Nov 8, 11:57 am, Martin Honnen <mahotr***@yahoo.de> wrote:
Show quote
> Kris wrote:
> > And xslt as follows:
>
> > <xsl:template match="/">
> >    <h1>Hello World</h1>
> >    <xsl:apply-templates select="/systems/system">
> > </xsl:template>
>
> > <xsl:template match="/systems/system">
> >    <b><xsl:value-of select="administrator"></b>
> > </xsl:template>
>
> > If I transform the document directly by calling the XSLT file from
> > within the XML document, I see:
> > <h1>Hello World</h1><b>John Doe</b>
>
> > However, if I use the XslCompiledTransform.Transform() method, I see:
> > <b>John Doe</b>
>
> > I guess this method is technically working correctly as it matches the
> > pattern of the XML document, but it's a tad frustrating as I have code
> > I need to drop in at the root of the document before that section gets
> > transformed.  Any ideas on a workaround?
>
> Does it improve things when you use
>
> <xsl:template match="/">
>     <h1>Hello World</h1>
>     <xsl:apply-templates select="systems/system">
> </xsl:template>
>
> <xsl:template match="systems/system">
>     <b><xsl:value-of select="administrator"></b>
> </xsl:template>
>
> ?
>
> Putting in a root element might also be a good idea e.g. assuming you
> want to create a snippet of HTML then a div container makes sense:
>
> <xsl:output method="html"/>
>
> <xsl:template match="/">
>   <div>
>     <h1>Hello World</h1>
>     <xsl:apply-templates select="systems/system">
>   </div>
> </xsl:template>
>
> <xsl:template match="systems/system">
>     <b><xsl:value-of select="administrator"></b>
> </xsl:template>
>
> --
>
>         Martin Honnen --- MVP XML
>        http://JavaScript.FAQTs.com/

Thanks for your help Martin, but I'm still seeing the same behavior.
It seems as though the XSLT Transformation isn't picking up the root
of the document. It picks up "systems/system" fine, but not "/"
Author
8 Nov 2007 5:29 PM
Martin Honnen
Kris wrote:

> Thanks for your help Martin, but I'm still seeing the same behavior.
> It seems as though the XSLT Transformation isn't picking up the root
> of the document. It picks up "systems/system" fine, but not "/"

I can't reproduce the problem, I have tried your sample XSLT, needed to
correct it to be well-formed, now looks as follows:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/">
     <h1>Hello World</h1>
     <xsl:apply-templates select="/systems/system"/>
     </xsl:template>

   <xsl:template match="/systems/system">
     <b>
       <xsl:value-of select="administrator"/>
     </b>
   </xsl:template>
</xsl:stylesheet>

XML input is

<?xml version="1.0" encoding="utf-8" ?>
<systems>
   <system>
     <administrator>John Doe</administrator>
   </system>
</systems>

C# code is

             XslCompiledTransform xsltProcessor = new
XslCompiledTransform();
             xsltProcessor.Load(@"..\..\XSLTFile1.xslt");

xsltProcessor.Transform(XmlReader.Create(@"..\..\XMLFile2.xml"), null,
Console.Out);


Result on the console is
<?xml version="1.0" encoding="ibm850"?><h1>Hello World</h1><b>John Doe</b>

so both the h1 and the b element is present.



--

    Martin Honnen --- MVP XML
    http://JavaScript.FAQTs.com/
Author
8 Nov 2007 6:37 PM
Kris
Martin,
Lets try with something similar to the actual code and data:

XML
DATA------------------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<src applid="APPLID" projectid="67">
  <project>Application</project>
  <portfolio>MyPortfolio</portfolio>
  <contacts>
    <contact>
      <full_name>abc</full_name>
      <email>a**@company.com</email>
      <phone>888-888-8888</phone>
      <role>ROLE</role>
    </contact>
    <contact>
      <full_name>def</full_name>
      <email>d**@company.com</email>
      <phone>999-999-9999</phone>
      <role>ROLE</role>
    </contact>
  </contacts>
  <reviews>
    <review>
      <reviewname>RVW</reviewname>
      <status>Entry</status>
      <isexpired>0</isexpired>
      <lastupdate>2007-06-11T11:47:23.627</lastupdate>
    </review>
  </reviews>
  <systems>
    <system>
      <hostname>a</hostname>
      <dnssuffix>company.com</dnssuffix>
      <ipaddress>127.0.0.1</ipaddress>
      <facility>Atlanta</facility>
      <environment>Production</environment>
      <role>DBA</role>
      <status>Live</status>
    </system>
    <system>
      <hostname>b</hostname>
      <dnssuffix>company.com</dnssuffix>
      <ipaddress>127.0.0.2</ipaddress>
      <facility>Syracuse</facility>
      <environment>Production</environment>
      <role>DBA</role>
      <status>Live</status>
    </system>
  </systems>
</src>

XSLT
-------------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/
Transform">
  <xsl:template match="/">
        <script language="javascript">
            //tabBar = new TabBar()
            //    tabBar.AddTab("Clearance","tab_0",true, true);
            //    tabBar.AddTab("Personnel","tab_1",false, true);
            //tabBar.Build();
        </script>
    <h1>Hello World!</h1>
        <xsl:apply-templates select="src" />
        <xsl:apply-templates select="src/contacts" />
        <xsl:apply-templates select="src/reviews" />
        <xsl:apply-templates select="src/systems" />
    </xsl:template>
  <xsl:template match="src">
        <div id="tab_0" class="tab_on">
            <div class="header"><h3 class="header"><xsl:value-of
select="project" /></h3></div>
            <table class="table_data">
                <tr><td class="label">APPLID:</td><td><xsl:value-of
select="@applid" /></td></tr>
                <tr><td class="label">Portfolio</td><td><xsl:value-of
select="portfolio" /></td></tr>
            </table>
        </div>
    </xsl:template>

    <xsl:template match="src/contacts">
        <div id="tab_1" class="tab_on">
            <div class="header"><h3 class="header">Application Contacts</h3></
div>
            <table class="table_data">
                <tr>
                    <th>Name</th>
                    <th>Email</th>
                    <th>Phone</th>
                    <th>Role</th>
                </tr>
            <xsl:for-each select="contact">
                <tr>
                    <td><xsl:value-of select="full_name" /></td>
                    <td>
                        <xsl:element name="A">
                                <xsl:attribute name="href">mailto:<xsl:value-of
select="email" /></xsl:attribute>
                                <xsl:value-of select="email" />
                            </xsl:element>
                    </td>
                    <td><xsl:value-of select="phone" /></td>
                    <td><xsl:value-of select="role" /></td>
                </tr>
            </xsl:for-each>
            </table>
        </div>
    </xsl:template>

    <xsl:template match="src/reviews">
        <div id="tab_2" class="tab_on">
            <div class="header"><h3 class="header">Reviews</h3></div>
            <table class="table_data">
                <tr>
                    <th>Name</th>
                    <th>Status</th>
                    <th>Expired</th>
                    <th>Last Update</th>
                </tr>
            <xsl:for-each select="review">
                <tr>
                    <td><xsl:value-of select="name" /></td>
                    <td><xsl:value-of select="status" /></td>
                    <td><xsl:value-of select="isexpired" /></td>
                    <td><xsl:value-of select="lastupdate" /></td>
                </tr>
            </xsl:for-each>
            </table>
        </div>
    </xsl:template>

    <xsl:template match="src/systems">
        <div id="tab_3" class="tab_on">
            <div class="header"><h3 class="header">Systems</h3></div>
            <table class="table_data">
                <tr>
                    <th>Host</th>
                    <th>IP Address</th>
                    <th>Facility</th>
                    <th>Environment</th>
                    <th>Role</th>
                    <th>Status</th>
                </tr>
            <xsl:for-each select="system">
                <tr>
                    <td>
                        <xsl:element name="A">
                            <xsl:attribute name="href">default.aspx?dns=<xsl:value-of
select="hostname" /></xsl:attribute>
                            <xsl:value-of select="hostname" />.<xsl:value-of
select="dnssuffix" />
                        </xsl:element>
                    </td>
                    <td>
                        <xsl:element name="A">
                            <xsl:attribute name="href">default.aspx?ipstart=<xsl:value-of
select="ipaddress" /></xsl:attribute>
                            <xsl:value-of select="ipaddress" />
                        </xsl:element>
                    </td>
                    <td><xsl:value-of select="facility" /></td>
                    <td><xsl:value-of select="environment" /></td>
                    <td><xsl:value-of select="role" /></td>
                    <td><xsl:value-of select="status" /></td>
                </tr>
            </xsl:for-each>
            </table>
        </div>
    </xsl:template>
</xsl:stylesheet>

CODE
---------------------------------------------------------------------------------------------

Sorry, I'm stuck using VB here...

Private Function TransformData(ByVal data As XmlDocument, ByVal
stylesheet As String) As String
    Dim xslCompiledTransform As New XslCompiledTransform
    Dim xPath As XPathNavigator = data.DocumentElement.CreateNavigator()
    Dim sb As New StringBuilder
    Dim sw As New StringWriter(sb)
    Dim xmlWriter As New XmlTextWriter(sw)

    xslCompiledTransform.Load(stylesheet)
    xslCompiledTransform.Transform(xPath, Nothing, xmlWriter)
    Return sb.ToString()
End Function

OUTPUT
-------------------------------------------------------------------------------
Outout when applying the stylesheet to the data in IE6 is fine. Output
from the TransformData function is:

<div id="tab_0" class="tab_on">
   <div class="header"><h3 class="header">Application</h3></div>
   <table class="table_data">
      <tr><td class="label">APPLID:</td><td>APPLID</td></tr>
      <tr><td class="label">Portfolio</td><td>MyPortfolio</td></tr>
   </table>
</div>
Author
9 Nov 2007 3:32 PM
Martin Honnen
Kris wrote:

> Private Function TransformData(ByVal data As XmlDocument, ByVal
> stylesheet As String) As String
>     Dim xslCompiledTransform As New XslCompiledTransform
>     Dim xPath As XPathNavigator = data.DocumentElement.CreateNavigator()
>     Dim sb As New StringBuilder
>     Dim sw As New StringWriter(sb)
>     Dim xmlWriter As New XmlTextWriter(sw)
>
>     xslCompiledTransform.Load(stylesheet)
>     xslCompiledTransform.Transform(xPath, Nothing, xmlWriter)
>     Return sb.ToString()
> End Function


The problem is that you pass
   data.DocumentElement.CreateNavigator()
to the Transform method, use
   data.CreateNavigator()
instead and the stylesheet has a root node (/) to operate on.

--

    Martin Honnen --- MVP XML
    http://JavaScript.FAQTs.com/
Author
9 Nov 2007 5:54 PM
Kris
On Nov 9, 10:32 am, Martin Honnen <mahotr***@yahoo.de> wrote:
Show quote
> Kris wrote:
> > Private Function TransformData(ByVal data As XmlDocument, ByVal
> > stylesheet As String) As String
> >    Dim xslCompiledTransform As New XslCompiledTransform
> >    Dim xPath As XPathNavigator = data.DocumentElement.CreateNavigator()
> >    Dim sb As New StringBuilder
> >    Dim sw As New StringWriter(sb)
> >    Dim xmlWriter As New XmlTextWriter(sw)
>
> >    xslCompiledTransform.Load(stylesheet)
> >    xslCompiledTransform.Transform(xPath, Nothing, xmlWriter)
> >    Return sb.ToString()
> > End Function
>
> The problem is that you pass
>    data.DocumentElement.CreateNavigator()
> to the Transform method, use
>    data.CreateNavigator()
> instead and the stylesheet has a root node (/) to operate on.
>
> --
>
>         Martin Honnen --- MVP XML
>        http://JavaScript.FAQTs.com/

That works wonderfully! Thank you so much!
It's always the silly stuff like that that gets you huh?

AddThis Social Bookmark Button