[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] Problems with mixed content and inline elements when transforming XHTML into another XML format


Subject: RE: [xsl] Problems with mixed content and inline elements when transforming XHTML into another XML format
From: Tony Kinnis <kinnist@xxxxxxxxx>
Date: Mon, 27 Feb 2006 02:13:41 -0800 (PST)

Great suggestion. That would be close to what I am looking for,
although the definition of "inline" in the two xml schemas I am
translating from/to is different. However, I will keep this in mind
when I am evaluating the processor I will be using. It could come in
handy for some other things I will be doing in the near future.

--- Michael Kay <mike@xxxxxxxxxxxx> wrote:

> > 
> > The function is-inline is generating a sequence with several
> elements.
> > I am wondering if the way this is done is most efficient. The list
> is
> > getting a little longer than I expected and I may add a few more
> > elements before it is all said and done. Is there a way I can
> declare
> > the set of tags I want to be included rather than building up this
> big
> > conditional?
> 
> Very often with a long list like this, you find that the elements are
> all
> members of the same substitution group in the schema. So with a
> schema-aware
> processor, you can use the construct 
> 
> . instance of schema-element(inline-element)
> 
> to select them all.
> 
> This may or may not be useful in your situation; but it's just one
> example
> of the ways that making stylesheets schema-aware can improve the
> robustness
> of your code.
> 
> Michael Kay
> http://www.saxonica.com/
> 
> 
> > 
> > For example: 
> > 
> > INSTEAD OF:
> > <xsl:sequence select="($node instance of text() and
> > normalize-space($node)) 
> >             or
> > $node[self::u|self::b|self::i|self::strong|self::span|self::em
> > |self::br|self::img|self::font|self::a]"/>
> > 
> > COULD I:
> > Declare a list of all tags I want considered...
> > <xsl:variable name="inlineElements"
> > select="u,b,i,strong,span,em,br,img,font,a"/>
> > 
> > <xsl:sequence select="($node instance of text() and
> > normalize-space($node)) 
> >             or inList($node, $inlineElements)"/>
> > 
> > Realizing I just made up this mythical function "inList". I am
> trying
> > to make it easier to add/subtract from the list and maybe improve
> the
> > readability some. Is there anything close to this that will perform
> > well?
> > 
> > Thanks again for help.
> > 
> > ----
> > In case anyone else is looking for the final script I have included
> it
> > here. I am guessing all of this was rather obvious to all of you. 
> > 
> > <?xml version="1.0" encoding="UTF-8"?>
> > <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> > version="2.0"
> >     xpath-default-namespace="http://www.w3.org/1999/xhtml"
> >     xmlns:f="http://localhost"
> >     xmlns:xs="http://www.w3.org/2001/XMLSchema"
> >     xmlns:my="http://localhost/markup.xsd">
> >     
> >     <xsl:output indent="yes" method="xml" encoding="UTF-8"
> > standalone="no"/>
> >     
> >     <xsl:template match="@*|node()">
> >         <xsl:copy>
> >             <xsl:for-each-group select="@*|node()"
> > group-adjacent="f:is-inline(.)">
> >                 <xsl:choose>
> >                     <xsl:when test="current-grouping-key()">
> >                         <xsl:element name="my:textnode">
> >                             <xsl:copy>
> >                                 <xsl:apply-templates
> > select="current-group()"/>
> >                             </xsl:copy>
> >                         </xsl:element>
> >                     </xsl:when>
> >                     <xsl:otherwise>                        
> >                         <xsl:apply-templates 
> > select="current-group()"/>
> >                     </xsl:otherwise>
> >                 </xsl:choose>
> >             </xsl:for-each-group>
> >         </xsl:copy>    
> >     </xsl:template>
> >     
> >     <xsl:function name="f:is-inline" as="xs:boolean">
> >         <xsl:param name="node" as="node()"/>
> >         <xsl:sequence select="($node instance of text() and
> > normalize-space($node)) 
> >             or
> > $node[self::u|self::b|self::i|self::strong|self::span|self::em
> > |self::br|self::img|self::font|self::a]"/>
> >     </xsl:function>
> > </xsl:stylesheet>
> > 
> > This will wrap all elements that are in the select clause of the
> > sequence above in a tag called called <my:textnode>.
> > 
> > --- Tony Kinnis <kinnist@xxxxxxxxx> wrote:
> > 
> > > Hello all, 
> > > 
> > > My apologies in advance for reposting. I sent this question a few
> > > days
> > > ago and didn't receive a response. Maybe it was simply over 
> > looked or
> > > even ignored. :) In case it is the former I am sending it again.
> > > 
> > > Thanks in advance for any help you can give. See below for the
> > > posting.
> > > 
> > > >>-- repost--<<
> > > 
> > > Sorry to keep asking about this problem but I am still 
> > having issues.
> > > The change you mention below does remove the error but now it
> never
> > > hits the block of code to wrap the elements in the textnode. It
> is
> > > simply outputting the input verbatim. Stepping through it in a
> > > debugger
> > > it shows that it steps into the for-each-group statement then
> right
> > > into the otherwise clause, outputs the entire document then it
> exits
> > > processing as complete. It seems as though it is missing a
> statement
> > > in
> > > the otherwise clause that causes it to recurse on the elements. I
> > > tried a couple of different things with that but they were all
> wrong
> > > and didn't produce the results I wanted.
> > > 
> > > See the previous message below for the input, stylesheet and
> desired
> > > output because I think something is missing here or I am not
> asking
> > > my
> > > question correctly. For convenience here is the entire stylesheet
> > > including the change you suggested. Once again thanks for your
> help.
> > > 
> > > <?xml version="1.0" encoding="UTF-8"?>
> > > <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> > > version="2.0"
> > >     xpath-default-namespace="http://www.w3.org/1999/xhtml"
> > >     xmlns:f="http://whatever"
> > >     xmlns:xs="http://www.w3.org/2001/XMLSchema">
> > >     
> > >     <xsl:template match="/">
> > >         <xsl:copy>
> > >             <xsl:for-each-group select="node()"
> > > group-adjacent="f:is-inline(.)">
> > >                 <xsl:choose>
> > >                     <xsl:when test="current-grouping-key()">
> > >                         <textnode><xsl:copy-of
> > > select="current-group()"/></textnode>
> > >                     </xsl:when>
> > >                     <xsl:otherwise>
> > >                         <xsl:copy-of select="current-group()"/>
> > >                     </xsl:otherwise>
> > >                 </xsl:choose>
> > >             </xsl:for-each-group>
> > >         </xsl:copy>   
> > >     </xsl:template>
> > >     
> > >     <xsl:function name="f:is-inline" as="xs:boolean">
> > >         <xsl:param name="node" as="node()"/>
> > >         <xsl:sequence select="$node instance of text() or
> > >
> > $node[self::u|self::b|self::i|self::strong|self::span|self::em
> > |self::br]"/>
> > >     </xsl:function>
> > > </xsl:stylesheet>
> > > 
> > > > --- Michael Kay <mike@xxxxxxxxxxxx> wrote:
> > > > 
> > > > > > 
> > > > > > I keep getting this error...
> > > > > > 
> > > > > > Description: A sequence of more than one item is not 
> > allowed as
> > > > the
> > > > > > first argument of f:is-inline()
> > > > > > URL: http://www.w3.org/TR/xpath20/#ERRXPTY0004
> > > > > 
> > > > > Sorry, the code should have said
> group-adjacent="f:is-inline(.)"
> 
=== message truncated ===


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 


Current Thread
Keywords