How to xsl:apply-templates while xsl:copy-of?

View: New views
5 Messages — Rating Filter:   Alert me  

How to xsl:apply-templates while xsl:copy-of?

by Alain Gilbert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I'm using xalan-2.7.0 (the same applies to version 2.7.1) and I'd like the transform to apply-templates while copying a set of nodes from the template into the result document.

I have attached the print.xsl template. Look at line 18 of print.xsl for the template "addInlineText" declaration and at line 10 for its call. At line 21, how to apply-templates while copying the template parameter?

In other words, I'd like the template that match "html:p" to be applied when the template "addField" is called with the parameter "value" with a set of node as value.

Is it possible to do it with XSLT 1.0? I'd like to avoid a second pass to apply the html:* templates.

Thanks,
Alain Gilbert



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

<xsl:output method="xml" version="1.0" omit-xml-declaration="no"  />
 
<xsl:template name="fragment">
        <fo:block>
                <xsl:call-template name="addInlineText">
                        <xsl:with-param name="value">
                                <html:p>Testing HTML in labels</html:p>
                        </xsl:with-param>
                </xsl:call-template>
          </fo:block>
</xsl:template>
 
<xsl:template name="addInlineText">
        <xsl:param name="value" />
        <fo:block>
                <xsl:copy-of select="$value" />
        </fo:block>
</xsl:template>
   
<xsl:template match="/">
        <fo:root>
                <fo:layout-master-set>
                        <fo:simple-page-master master-name="simpleA4"
                                page-height="29.7cm" page-width="21cm" margin-top="2cm"
                                margin-bottom="2cm" margin-left="2cm"
                                margin-right="2cm">
                                <fo:region-body />
                        </fo:simple-page-master>
                </fo:layout-master-set>
                <fo:page-sequence master-reference="simpleA4">
                        <fo:flow flow-name="xsl-region-body">
                                <xsl:call-template name="fragment" />
                        </fo:flow>
                </fo:page-sequence>
        </fo:root>
</xsl:template>

<xsl:template match="html:p">
<fo:block>
  <xsl:value-of select="text()"/>
</fo:block>
</xsl:template>

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

</xsl:stylesheet>

data.xml (14 bytes) Download Attachment

Parent Message unknown RE: How to xsl:apply-templates while xsl:copy-of?

by Alain Gilbert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.

Thanks Tomas,

 

The print.xsl transformation is generated from another source and the addInlineText value parameter may contain arbitrary html content. I have simplified the print.xsl template to its bare minimum to show my problem. In general there will be many calls to addInlineText with varying values.

 

My intent is to use the xhtml2fo.xsl template provided by www.antennahouse.com to process the XHTML to FO transformation of html:* nodes.

 

Hopes this clarify my original post.

 

Alain Gilbert

 


From: Tomas Studva [mailto:tstudva@...]
Sent: Tuesday, September 08, 2009 11:00 AM
To: Alain Gilbert
Subject: Re: How to xsl:apply-templates while xsl:copy-of?

 

Hi Gilbert,
I think it is not possible to match template against a parameter. Template can match only nodes in input XML. The desired effect you can get, if the "addInlineText" template will call template "html:p" with some parameter.

<xsl:call-template name="etc">
  <xsl:param name="param1" select="$value" />
</xsl:call-template>

Apply template calls are very similiar to call-template calls.

But in general, I don't see what are you trying to achieve.

Tomas Studva

On Tue, Sep 8, 2009 at 4:30 PM, Alain Gilbert <AGilbert@...> wrote:

Hi,

I'm using xalan-2.7.0 (the same applies to version 2.7.1) and I'd like the transform to apply-templates while copying a set of nodes from the template into the result document.

I have attached the print.xsl template. Look at line 18 of print.xsl for the template "addInlineText" declaration and at line 10 for its call. At line 21, how to apply-templates while copying the template parameter?

In other words, I'd like the template that match "html:p" to be applied when the template "addField" is called with the parameter "value" with a set of node as value.

Is it possible to do it with XSLT 1.0? I'd like to avoid a second pass to apply the html:* templates.

Thanks,
Alain Gilbert

 


Re: How to xsl:apply-templates while xsl:copy-of?

by Mukul Gandhi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Alain,
   I see the problem description a bit vague, to suggest the solution
to your real problem.

Within your problem description, you mention, [to be applied when the
template "addField"]. But I don't see any template with the name
"addField" in your XSLT stylesheet. Are you refereeing to,
"addInlineText" and not "addField"?

You mention input XML as:
<root/>

What is the purpose of this input, and how it is meant to be used by
your stylesheet?

If you can post a small input XML (a small replica of the real input),
and the desired output (a small replica of the real output desired),
with a little bit of more clarity about the transformation required, I
guess, the problem might be solvable.

I would also like to mention, that any conventional two pass problem
can be solved much easily with xx:node-set extension function in a
single stylesheet. Xalan-J does support, xx:node-set extension
function.

On Tue, Sep 8, 2009 at 8:00 PM, Alain Gilbert <AGilbert@...> wrote:

> Hi,
>
> I'm using xalan-2.7.0 (the same applies to version 2.7.1) and I'd like the transform to apply-templates while copying a set of nodes from the template into the result document.
>
> I have attached the print.xsl template. Look at line 18 of print.xsl for the template "addInlineText" declaration and at line 10 for its call. At line 21, how to apply-templates while copying the template parameter?
>
> In other words, I'd like the template that match "html:p" to be applied when the template "addField" is called with the parameter "value" with a set of node as value.
>
> Is it possible to do it with XSLT 1.0? I'd like to avoid a second pass to apply the html:* templates.
>
> Thanks,
> Alain Gilbert


--
Regards,
Mukul Gandhi

Parent Message unknown RE: How to xsl:apply-templates while xsl:copy-of?

by Alain Gilbert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

When I rewrite the addInlineText template as:

<xsl:template name="addInlineText">
  <xsl:param name="value" />
  <fo:block>
    <xsl:for-each select="$value" >
      <xsl:copy/>
      <xsl:apply-templates/>
    </xsl:for-each>
  </fo:block>
</xsl:template>

I do get the desired behavior with the Altova XSLT engine, built in the XMLSpy product.

However, when trying the same with Xalan, I get this error:
  SystemID: print.xsl; Line#: 20; Column#: 33
  org.apache.xpath.XPathException: Can not convert #RTREEFRAG to a NodeList!
    at org.apache.xpath.objects.XObject.error(XObject.java:703)
    at org.apache.xpath.objects.XObject.iter(XObject.java:406)
    at org.apache.xpath.Expression.asIterator(Expression.java:250)
    at org.apache.xalan.templates.ElemForEach.transformSelectedNodes(ElemForEach.java:333)

Any help greatly appreciated,
Alain Gilbert

-----Original Message-----
From: Alain Gilbert
Sent: Tuesday, September 08, 2009 10:31 AM
To: 'xalan-j-users@...'
Subject: How to xsl:apply-templates while xsl:copy-of?

Hi,

I'm using xalan-2.7.0 (the same applies to version 2.7.1) and I'd like the transform to apply-templates while copying a set of nodes from the template into the result document.

I have attached the print.xsl template. Look at line 18 of print.xsl for the template "addInlineText" declaration and at line 10 for its call. At line 21, how to apply-templates while copying the template parameter?

In other words, I'd like the template that match "html:p" to be applied when the template "addField" is called with the parameter "value" with a set of node as value.

Is it possible to do it with XSLT 1.0? I'd like to avoid a second pass to apply the html:* templates.

Thanks,
Alain Gilbert


Re: How to xsl:apply-templates while xsl:copy-of?

by Mukul Gandhi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Alain,
   The reason, why xsl:for-each select="$value" is working with
XMLSpy, is because XMLSpy is using a XSLT 2.0 engine, which treats
$value as a node-set.

Whereas, $value if a RTF (result tree fragment) in XSLT 1.0. An
expression, select="$value" will give an error, as you just found,
with XSLT 1.0.

To make this work with Xalan-J, you need to use the xx:node-set
extension function. Please refer,
http://xml.apache.org/xalan-j/extensionslib.html#exslt for more
information in this regard.

So you would need to do something, like:
xx:node-set($value)

or perhaps,
xx:node-set($value)/*

xx:node-set($value) behaves similar to, a 2.0 $value

On Tue, Sep 8, 2009 at 9:29 PM, Alain Gilbert <AGilbert@...> wrote:

> When I rewrite the addInlineText template as:
>
> <xsl:template name="addInlineText">
>  <xsl:param name="value" />
>  <fo:block>
>    <xsl:for-each select="$value" >
>      <xsl:copy/>
>      <xsl:apply-templates/>
>    </xsl:for-each>
>  </fo:block>
> </xsl:template>
>
> I do get the desired behavior with the Altova XSLT engine, built in the XMLSpy product.
>
> However, when trying the same with Xalan, I get this error:
>  SystemID: print.xsl; Line#: 20; Column#: 33
>  org.apache.xpath.XPathException: Can not convert #RTREEFRAG to a NodeList!
>    at org.apache.xpath.objects.XObject.error(XObject.java:703)
>    at org.apache.xpath.objects.XObject.iter(XObject.java:406)
>    at org.apache.xpath.Expression.asIterator(Expression.java:250)
>    at org.apache.xalan.templates.ElemForEach.transformSelectedNodes(ElemForEach.java:333)
>
> Any help greatly appreciated,
> Alain Gilbert



--
Regards,
Mukul Gandhi