Ureader.com  
Microsoft software help and Community
   home   |   control panel login   |   archive   |  
 
XML
data.xmlanalysis
mappoint.webservice
msf
msxml-webrelease
netmyservices.sdk
passport.sdk
soap
soapsdk
uddi.general
uddi.programming
uddi.specification
xml
xmlsqlwebrelease
xsl
  
 
date: Fri, 4 Jul 2008 08:44:01 -0700,    group: microsoft.public.xsl        back       


Using XSLT to transform XHTML to XHTML (again!)   
Dear Newsgroup

I have an input XHTML document containing multiple topics. It contains topic 
names in h1 tags followed by content elements at the same level, and I want 
the transform to be able to select a single topic as specified by a parameter 
and output the topic as valid XHTML. I'm OK with the parameter but I cannot 
figure out how to get just the topic I want. Here is the input:

------- input2.xhtml --------
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  <head>
    <title>Fruits</title>
  </head>
  <body>
    <h1>Apples</h1>
    <p>Round fruits that grow on trees.</p>
    <p>They taste OK.</p>
    <h1>Bananas</h1>
    <p>Yellow fruits that grow in clumps.</p>
    <p>They taste nice as a smoothie.</p>
    <h1>Turnips</h1>
    <p>Warty vegetable, OK if roasted.</p>
  </body>
</html>
------- input2.xhtml --------


------- transform2.xslt ---------
<xsl:stylesheet version="1.0" 
 xmlns="http://www.w3.org/1999/xhtml"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xhtml="http://www.w3.org/1999/xhtml"
  exclude-result-prefixes="xhtml xsl">
 
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" 
  doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" 
  doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>

<xsl:param name="title"/>

<xsl:variable name="first">4</xsl:variable>

<xsl:variable name="last">6</xsl:variable>

<xsl:template match="/">
  <html>
  <head>
  <title> <xsl:value-of select="$title"/> </title>
  </head>
  <body> 
      
    <xsl:for-each select="xhtml:html//xhtml:h1|xhtml:html//xhtml:p">
        <xsl:if test="position() >= $first and position() <= $last">
          <xsl:copy-of select="."></xsl:copy-of>
        </xsl:if>
    </xsl:for-each>
      
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>
------- transform2.xslt ---------


---- wanted-output.xhtml -----
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html 
xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<title>Bananas</title>
	</head>
	<body>
		<h1>Bananas</h1>
		<p>Yellow fruits that grow in clumps.</p>
		<p>They taste nice as a smoothie.</p>
	</body>
</html>
---- wanted-output.xhtml -----

In this case I pass in "Bananas" as the 'title' parameter and I want my 
output to be just the topic associated with Bananas (eg the position() 
between 4 and 6). But the only way I can make it work is by hard-wiring the 
'first' and 'last' position values which is not useful :) In my transform I 
want something like:

<xsl:variable name="first" select="position-of(text()=$title)"/>
<xsl:variable name="last" select="position-of(text()=$title) and position() 
> $first"/>

But somehow I don't think that will work :) Any pointers would be welcome.

Kind regards, Will Rayer
date: Fri, 4 Jul 2008 08:44:01 -0700   author:   William Rayer

Re: Using XSLT to transform XHTML to XHTML (again!)   
William Rayer wrote:

> But somehow I don't think that will work :) Any pointers would be welcome.

Here is how I would solve that:

<xsl:stylesheet version="1.0"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xhtml="http://www.w3.org/1999/xhtml"
   exclude-result-prefixes="xhtml xsl">

   <xsl:output method="xml" indent="no" omit-xml-declaration="yes"
   doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
 
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>

<xsl:param name="title"/>

<xsl:template match="@* | node()">
   <xsl:copy>
     <xsl:apply-templates select="@* | node()"/>
   </xsl:copy>
</xsl:template>

<xsl:template match="xhtml:h1">
   <xsl:if test=". = $title">
     <xsl:copy>
       <xsl:apply-templates select="@* | node()"/>
     </xsl:copy>
   </xsl:if>
</xsl:template>

<xsl:template match="xhtml:p">
   <xsl:if test="preceding-sibling::xhtml:h1[1] = $title">
     <xsl:copy>
       <xsl:apply-templates select="@* | node()"/>
     </xsl:copy>
   </xsl:if>
</xsl:template>

</xsl:stylesheet>



-- 

	Martin Honnen --- MVP XML
	http://JavaScript.FAQTs.com/
date: Fri, 04 Jul 2008 18:04:07 +0200   author:   Martin Honnen

Re: Using XSLT to transform XHTML to XHTML (again!)   
Hi Martin

Many thanks - that seems to work fine! But is it possible to do it from 
within the context of a single template match on the root node? I am trying 
to keep the HTML output in the form:

<xsl:template match="/">
  <html>
  <head>
  <title> <xsl:value-of select="$title"/> </title>
  </head>
  <body> 
  
      <!-- XSLT stuff in here -->

  </body>
  </html>
</xsl:template>

as I find this easier to understand.?
date: Fri, 4 Jul 2008 09:23:00 -0700   author:   William Rayer

Re: Using XSLT to transform XHTML to XHTML (again!)   
William Rayer wrote:

> Many thanks - that seems to work fine! But is it possible to do it from 
> within the context of a single template match on the root node? I am trying 
> to keep the HTML output in the form:
> 
> <xsl:template match="/">
>   <html>
>   <head>
>   <title> <xsl:value-of select="$title"/> </title>
>   </head>
>   <body> 
>   
>       <!-- XSLT stuff in here -->
> 
>   </body>
>   </html>
> </xsl:template>
> 
> as I find this easier to understand.?

Well using the identity transformation template and adding templates to 
perform some changes is a fundamental XSLT approach you should try to 
become familiar with.

If you really insist on one template and spelling out the structure 
again instead of simply copying it then you need


<xsl:stylesheet version="1.0"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xhtml="http://www.w3.org/1999/xhtml"
   exclude-result-prefixes="xhtml xsl">

   <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"
   doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
 
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>

<xsl:param name="title"/>

<xsl:variable name="h1" select="/xhtml:html/xhtml:body/xhtml:h1[. = 
$title]"/>

<xsl:template match="/">
   <html>
   <head>
   <title> <xsl:value-of select="$title"/> </title>
   </head>
   <body>

     <xsl:copy-of select="$h1 | 
$h1/following-sibling::xhtml:p[generate-id($h1) = 
generate-id(preceding-sibling::xhtml:h1[1])]"/>

   </body>
   </html>
</xsl:template>

</xsl:stylesheet>




-- 

	Martin Honnen --- MVP XML
	http://JavaScript.FAQTs.com/
date: Fri, 04 Jul 2008 18:52:21 +0200   author:   Martin Honnen

Re: Using XSLT to transform XHTML to XHTML (again!)   
Hi Martin

That is really neat - & even better it works :) I really appreciate you 
showing me this.

BTW I was also very interested by what you wrote:

> ... adding templates to 
> perform some changes is a fundamental XSLT approach you should try to 
> become familiar with.

I had to get to grips with XSLT about a year ago. Although I'm happy with 
most development tasks (C, C#, SQL etc) I found it very difficult to get to 
grips with transforms. I found this article 
<http://www.xfront.com/rescuing-xslt.html> which was written by soneone with 
the same issues (programming experience but problems getting to grips with 
transforms). His insight (to me) was to treat XSLT as a powerful templating 
language, allowing me to embed the desired HTML output in the XSLT and to 
treat the <xsl...> instructions as special tags that get values from the 
input XML. Anyway sorry to go on but I found XSLT much easier when following 
the 'template' approach. I understand it may be non-ideal and I may need to 
expand my XSLT later on.

Thanks again - Will Rayer


"Martin Honnen" wrote:

> William Rayer wrote:
> 
> > Many thanks - that seems to work fine! But is it possible to do it from 
> > within the context of a single template match on the root node? I am trying 
> > to keep the HTML output in the form:
> > 
> > <xsl:template match="/">
> >   <html>
> >   <head>
> >   <title> <xsl:value-of select="$title"/> </title>
> >   </head>
> >   <body> 
> >   
> >       <!-- XSLT stuff in here -->
> > 
> >   </body>
> >   </html>
> > </xsl:template>
> > 
> > as I find this easier to understand.?
> 
> Well using the identity transformation template and adding templates to 
> perform some changes is a fundamental XSLT approach you should try to 
> become familiar with.
> 
> If you really insist on one template and spelling out the structure 
> again instead of simply copying it then you need
> 
> 
> <xsl:stylesheet version="1.0"
>   xmlns="http://www.w3.org/1999/xhtml"
>   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>   xmlns:xhtml="http://www.w3.org/1999/xhtml"
>    exclude-result-prefixes="xhtml xsl">
> 
>    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"
>    doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
>  
> doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
> 
> <xsl:param name="title"/>
> 
> <xsl:variable name="h1" select="/xhtml:html/xhtml:body/xhtml:h1[. = 
> $title]"/>
> 
> <xsl:template match="/">
>    <html>
>    <head>
>    <title> <xsl:value-of select="$title"/> </title>
>    </head>
>    <body>
> 
>      <xsl:copy-of select="$h1 | 
> $h1/following-sibling::xhtml:p[generate-id($h1) = 
> generate-id(preceding-sibling::xhtml:h1[1])]"/>
> 
>    </body>
>    </html>
> </xsl:template>
> 
> </xsl:stylesheet>
> 
> 
> 
> 
> -- 
> 
> 	Martin Honnen --- MVP XML
> 	http://JavaScript.FAQTs.com/
>
date: Mon, 7 Jul 2008 08:51:01 -0700   author:   William Rayer

Google
 
Web ureader.com


    COPYRIGHT 2007, YARDI TECHNOLOGY LIMITED, ALL RIGHT RESERVE  |   contact us