0

This xsl:apply-templates instruction:

<xsl:if test="$item/tcm:Content/em:Office/em:Address">
    <address>
        <xsl:apply-templates mode="renderhtml" select="$item/tcm:Content/em:Office/em:Address/node()" />
    </address>
</xsl:if>

produces:

<p>
    My Office Address
    <br />XXXX Road
    <br />XXXX District
    <br />XXXX, XXXX.
    <br />PO Box XXXX
</p>

Now I want to store the produced html in a variable and later call another template to replace the first <p> element with <p property="v:street-address">, so that it the final result would be:

<p property="v:street-address">
    My Office Address
    <br />XXXX Road
    <br />XXXX District
    <br />XXXX, XXXX.
    <br />PO Box XXXX
</p>

Please suggest!!

Thanks

JLRishe
  • 99,490
  • 19
  • 131
  • 169
Manoj Singh
  • 7,569
  • 34
  • 119
  • 198

2 Answers2

1

In XSLT 1.0, you can only capture an output and apply templates to that output is if you are using a processor that supports the node-set() function. Assuming that you are, you can do something like this:

<xsl:if test="$item/tcm:Content/em:Office/em:Address">
    <address>
      <xsl:variable name="addressHtml">
        <xsl:apply-templates mode="renderhtml" 
                             select="$item/tcm:Content/em:Office/em:Address/node()" />
      </xsl:variable>
      <xsl:apply-templates select="msxsl:node-set($addressHtml)" 
                           mode="adjustAddressHtml" />
    </address>
</xsl:if>

...

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

  <xsl:template match="/" mode="adjustAddressHtml">
    <xsl:if test="p">
      <xsl:call-template name="Identity" />
    </xsl:if>
    <xsl:if test="not(p)">
      <xsl:call-template name="StartingP" />
    </xsl:if>
  </xsl:template>

  <xsl:template match="/p[1]" mode="adjustAddressHtml" name="StartingP">
    <p property="v:street-address">
      <xsl:apply-templates select="@* | node()" mode="adjustAddressHtml" />
    </p>
  </xsl:template>
JLRishe
  • 99,490
  • 19
  • 131
  • 169
  • what is exslt here? what need to be declared as I am using xslt 1.0 – Manoj Singh Feb 10 '13 at 16:51
  • `exslt` is just one of several namespaces that contain the `node-set()` function, depending on the processor. What XSLT processor are you using? – JLRishe Feb 10 '13 at 16:54
  • sorry for late response due to time difference, here is my top declaration – Manoj Singh Feb 11 '13 at 03:59
  • @ManojSingh What I'm asking is - what program, library, or framework are you using to execute the XSLT? – JLRishe Feb 11 '13 at 05:04
  • Ok, we are using xmlns:msxsl="urn:schemas-microsoft-com:xslt", I have used your logic in my code and working fine, now two things, 1) I need this to be implemented for first

    tag only 2) If there is no

    tag we need to add address data inside

    adress........

    , please suggest
    – Manoj Singh Feb 11 '13 at 05:41
0

Without a source XML document provided it is difficult to give a complete answer, but in general one can avoid the need of a two-pass transformation.

Instead, the XSLT code can be somethong as simple as:

Somewhere:

<xsl:apply-templates mode="renderhtml"
         select="$item/tcm:Content/em:Office/em:Address/>

Then:

 <xsl:template match="em:Address" mode="renderhtml">
  <address>
      <xsl:apply-templates mode="renderhtml" select="node()" />
  </address>
 </xsl:template>

 <xsl:template match="em:Address/node()" mode="renderhtml">
    <p>
     <xsl:if test="position() = 1">
      <xsl:attribute name="property">v:street-address</xsl:attribute>
     </xsl:if>
       <!-- The code that generates this:
        My Office Address
        <br />XXXX Road
        <br />XXXX District
        <br />XXXX, XXXX.
        <br />PO Box XXXX
         -->
    </p>
 </xsl:template>
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
  • I can change "renderHtml" as this is common for other xslt, please suggest some specific solution for this – Manoj Singh Feb 10 '13 at 18:10
  • 1
    @ManojSingh You have failed to provide the necessary information to give you a confident answer: a description of the format of the input XML along with an example, and enough of your XSLT to understand how its working (preferably more than the 5 lines you gave us, plus the XSLT for the `renderHtml` mode. You have also failed to answer a very simple query for information that I asked you two hours ago. – JLRishe Feb 10 '13 at 19:15
  • @ManojSingh, I completely agree with JLRishe -- when you post *such* questions you inevitably receive *such* answers. Please, value the time of the readers. – Dimitre Novatchev Feb 10 '13 at 19:43