Re: [xsl] variables and inline tags

Subject: Re: [xsl] variables and inline tags
From: Spencer Tickner <spencertickner@xxxxxxxxx>
Date: Wed, 4 May 2005 16:00:51 -0700
Ok, Sorry Guys

Thought I had it all worked out, but still having difficulties. Based
on the suggestions I believe my template for definition should look
something like this:

<xsl:template match="definition" mode="contentsection">

<xsl:choose>
       <xsl:when test="substring(def, 1, 1)=','">
		<p class="def"><strong>"<xsl:apply-templates
select="term"/>"</strong>,&#160;<xsl:apply-templates
select="def"/></p>
       </xsl:when>
       <xsl:otherwise>
           <p class="def"><strong>"<xsl:apply-templates
select="term"/>"</strong>&#160;<xsl:apply-templates select="def"/></p>
       </xsl:otherwise>
       </xsl:choose>


</xsl:template>
<!-- Defintion -->
<xsl:template match="def/text()">
  <!-- when a text node is inside a def, this template
       overrides the built-in template for text nodes,
       which simply copies out their values -->
  <xsl:choose>
  <xsl:when test="not(preceding-sibling::node()) and starts-with(.,',')">
    <!-- truncates the first character if it's a comma and this text
         node has no preceding siblings -->
    <xsl:value-of select="substring(., 2)"/>
  </xsl:when>
  <xsl:otherwise>
    <xsl:value-of select="."/>
  </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="def">
	<xsl:apply-templates select="text()|strong|em|sup|sub|u|insert|br|eacute"/>
 </xsl:template>
 <xsl:template match="term">
 	<xsl:apply-templates select="text()|strong|em|sup|sub|u|insert|br|eacute"/>
 </xsl:template>

Right, now that looks all fine to me, except I have these other
templates normalizing all my content comming through the pipe:

 <xsl:template match="text()[preceding-sibling::node() and
                            following-sibling::node()]">
  <xsl:variable name="ns" select="normalize-space(concat('x',.,'x'))"/>
  <xsl:value-of select="substring( $ns, 2, string-length($ns) - 2 )" />
</xsl:template>

<xsl:template match="text()[preceding-sibling::node() and
                            not( following-sibling::node() )]">
  <xsl:variable name="ns" select="normalize-space(concat('x',.))"/>
  <xsl:value-of select="substring( $ns, 2, string-length($ns) - 1 )" />
</xsl:template>

<xsl:template match="text()[not( preceding-sibling::node() ) and
                            following-sibling::node()]">
  <xsl:variable name="ns" select="normalize-space(concat(.,'x'))"/>
  <xsl:value-of select="substring( $ns, 1, string-length($ns) - 1 )" />
</xsl:template>

<xsl:template match="text()[not( preceding-sibling::node() ) and
                            not( following-sibling::node() )]">
  <xsl:value-of select="normalize-space(.)"/>
</xsl:template>

As expected an error occurs when trying to do both of these at the same time:

Ambiguous rule match for .......... Matches both
"text()[not(preceding-sibling::node()) and
not(following-sibling::node())]" and def/text() .......

I've tried a couple of work arounds but I always end up with either
 a) the problem before, <em> gets dropped
 b) spacing problems from badly-formatted content

Thanks for any help you can offer,

Spencer

On 5/4/05, Spencer Tickner <spencertickner@xxxxxxxxx> wrote:
> Hi Guys,
>
> Thanks for the great feed-back. It took a bit to figure out how to
> modify your template to work in my context (I was matching text-nodes
> to remove excess whitespace around inline tags), but I got her working
> so thanks for comming through once again.
>
> Cheers,
>
> Spencer
>
> On 5/4/05, Wendell Piez <wapiez@xxxxxxxxxxxxxxxx> wrote:
> > Spencer,
> >
> > The tricky thing here is that to remove the comma without messing with
the
> > other nodes (as you discovered, when you use the value of the <def> its
> > children aren't processed), you need to get at it all the way down at the
> > level of the text node. But not just any text node is of interest --
> > actually it's only those that are the first thing inside a <def>, which
> > have a comma.
> >
> > So:
> >
> > <xsl:template match="def/text()">
> >    <!-- when a text node is inside a def, this template
> >         overrides the built-in template for text nodes,
> >         which simply copies out their values -->
> >    <xsl:when test="not(preceding-sibling::node() and starts-with(.,',')">
> >      <!-- truncates the first character if it's a comma and this text
> >           node has no preceding siblings -->
> >      <xsl:value-of select="substring(., 2)"/>
> >    </xsl:when>
> >    <xsl:otherwise>
> >      <xsl:value-of select="."/>
> >    </xsl:otherwise>
> > </xsl:template>
> >
> > You may have to adjust this match pattern, or even construct a separate
> > mode, to keep this sufficiently isolated from the way you want most text
> > nodes to be processed. (I assume you generally don't want to truncate
> > initial commas in text nodes.) And it will work irrespective of whether
the
> > results are bound to a variable, or simply copied out.
> >
> > If it's mysterious to you why this works -- like most XSLT mysteries, it
> > comes back to the processing model (that is, what the processor does when
> > you say "apply-templates" or let it default to that).
> >
> > I hope this helps,
> > Wendell
> >
> > At 04:52 PM 5/4/2005, you wrote:
> > >Having problems with variables, applying templates and parsing
> > >strings. Been working on it all day and can't seem to wrap my mind
> > >around it.
> > >
> > >Here is my simplified xml:
> > >
> > ><definition>
> > >   <term>recognized</term>
> > >   <def>, under the <em>Company Act</em></def>
> > ></definition>
> > >
> > >What I need to do is substring the def information when it starts with
> > >a comma, ie:
> > >
> > >with comma
> > ><p class="def">"recognized", under the <em>Company Act</em></p>
> > >
> > >without comma
> > ><p class="def">"recognized" under the <em>Company Act</em></p>
> > >
> > >Ok, there's the background. I'm having problems because I'm using a
> > >variable to parse out the unwanted space in the with comma example
> > >above, then to get the variable I use a value-of statement which
> > >promptly drops the <em> tags. Any suggestions or advive would be
> > >appreciated.
> > >
> > >
> > >Here's my simplified xsl:
> > >
> > ><!-- Defintion -->
> > ><xsl:template match="definition" mode="contentsection">
> > >         <p class="def">
> > >         <xsl:choose>
> > >         <xsl:when test="substring(def, 1, 1)=','">
> > >                 <strong>"<xsl:apply-templates
> > >select="term"/>"</strong>,&#160;<xsl:variable name="uncommadef">
> > >                         <xsl:apply-templates select="def"/>
> > >                 </xsl:variable>
> > >
> > >                  <!-- Problem is here -->
> > >                 <xsl:value-of select="substring($uncommadef, 2)"/>
> > >         </xsl:when>
> > >         <xsl:otherwise>
> > >                 <strong>"<xsl:apply-templates
> > >select="term"/>"</strong>&#160;<xsl:apply-templates select="def"/>
> > >         </xsl:otherwise>
> > >         </xsl:choose>
> > >         </p>
> > >  </xsl:template>
> > >  <xsl:template match="term">
> > >         <xsl:apply-templates
> > > select="text()|strong|em|sup|sub|u|insert|br|eacute"/>
> > >  </xsl:template>
> > >  <xsl:template match="def">
> > >         <xsl:apply-templates
> > > select="text()|strong|em|sup|sub|u|insert|br|eacute"/>
> > >  </xsl:template>
> > ><!-- End of Definition -->
> >
> > ======================================================================
> > Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
> > Mulberry Technologies, Inc.                http://www.mulberrytech.com
> > 17 West Jefferson Street                    Direct Phone: 301/315-9635
> > Suite 207                                          Phone: 301/315-9631
> > Rockville, MD  20850                                 Fax: 301/315-8285
> > ----------------------------------------------------------------------
> >    Mulberry Technologies: A Consultancy Specializing in SGML and XML
> > ======================================================================

Current Thread