views:

33

answers:

3

I have to create slightly dynamic pdf (two variables) with two text blocks in different languages.

Most of the text in both blocks is static

I was thinking if I could create one template that would create xsl-fo for the layout. Then create two variables containing custom xml. Something like:

<xsl:variable name="TEXT_CONTENT_ENG" >
  <STATIC_TEXT> 
   <LABEL>Hello</LABEL>
   <REQUEST>Please pay your bill before </REQUEST>
  </STATIC_TEXT>
</xsl:variable>

Finally I could apply created template twice using these variables.

xsl appears to validate with given variable but I couldn't apply template to that xml. Tried and also document($TEXT_CONTENT_ENG) neither worked.

Is this even possible and how to do it?

A: 

Using xalan I was able to do it like this:

<xsl:apply-templates select="xalan:nodeset($TEXT_CONTENT_ENG)/STATIC_TEXT"/>

Similar function is also available for exslt

Priit
You don't have to use *:nodeset() function to do this, see: http://stackoverflow.com/questions/3626118/xslt-creating-a-map-in-xslt/3626283
Per T
A: 

Most of the text in both blocks is static

If this is true, then the proper XSLT way is inline data. From http://www.w3.org/TR/xslt#stylesheet-element

In addition, the xsl:stylesheet element may contain any element not from the XSLT namespace, provided that the expanded-name of the element has a non-null namespace URI. The presence of such top-level elements must not change the behavior of XSLT elements and functions defined in this document; for example, it would not be permitted for such a top-level element to specify that xsl:apply-templates was to use different rules to resolve conflicts. Thus, an XSLT processor is always free to ignore such top-level elements, and must ignore a top-level element without giving an error if it does not recognize the namespace URI. Such elements can provide, for example,

  • information used by extension elements or extension functions (see
    [14 Extensions]),

  • information about what to do with the result tree,

  • information about how to obtain the source tree,

  • metadata about the stylesheet,

  • structured documentation for the stylesheet.

<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform"&gt;
    <variable name="vRTF">
        <STATIC_TEXT xmlns="">
            <LABEL>Hello</LABEL>
            <REQUEST>Please pay your bill before </REQUEST>
        </STATIC_TEXT>
    </variable>
    <template match="/">
        <apply-templates
              select="document('')/*/xsl:variable[@name='vRTF']/node()"
              xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/&gt;
    </template>
    <template match="@*|node()">
        <copy>
            <apply-templates select="@* | node()"/>
        </copy>
    </template>
</stylesheet>

Output:

<STATIC_TEXT>
    <LABEL>Hello</LABEL>
    <REQUEST>Please pay your bill before </REQUEST>
</STATIC_TEXT>

Note: In XML 1.0 you can reset only default namespace.

Alejandro
A: 

Alejandro's answer is in general correct, but the unconventional use of namespaces is a little confusing, and he's wrapped the data in an unnecessary xsl:variable element, which is also a little confusing.

As long as you put your element in its own namespace, you can make it a child of the xsl:stylesheet element. You can then access it by using document(''), which returns the current XSLT document:

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

   <in:TEXT_CONTENT_ENG>
      <STATIC_TEXT> 
         <LABEL>Hello</LABEL>
         <REQUEST>Please pay your bill before </REQUEST>
      </STATIC_TEXT>
   </in:TEXT_CONTENT_ENG>

   <xsl:template match="/">
      <output>
         <xsl:apply-templates 
             select="document('')/xsl:stylesheet/in:TEXT_CONTENT_ENG/*"/>
      </output>
   </xsl:template>

   <xsl:template match="STATIC_TEXT">
      <xsl:text>The label is </xsl:text>
      <xsl:value-of select="LABEL"/>
      <xsl:text> and the request is </xsl:text>
      <xsl:value-of select="REQUEST"/>
   </xsl:template>

</xsl:stylesheet>
Robert Rossney
@Robert Rossney: About "unconventional use of namespaces", ja! Besides that ussing the XSLT namespace as default namespace isn't unconventional, in your answer you are ussing string values. That's why you aren't dealing with the typical namespace problem with inline data: despite the fact that it could be under the null namespace (with a parent under a not null namespace) all in scope namespaces (maybe declared in `stylesheet` element) are there. Only with XML 1.1 you could reset those namespace declarations as `xmlns:xsl=""`.
Alejandro
I should have said "unconventional use of the XSLT namespace as the default," really - your example is literally the first time I've ever seen anyone do that. That said, I don't understand the point that you're making about the "typical namespace problem." What problem is that?
Robert Rossney