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: Sun, 26 Feb 2006 17:42:17 -0800 (PST)
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(.)"
> > 
> > Michael Kay
> > http://www.saxonica.com/
> > 
> > > 
> > > In case this this matters I am debugging this using the Oxygen
> > editor
> > > for the mac. The processor I have selected is Saxon8B. Once again
> > help
> > > is much appreciated.
> > > 
> > > To make this easier here is the full xsl doc, input I am testing
> > and
> > > desired output....
> > > 
> > > XSL document...
> > > <?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(node())">
> > >                 <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>
> > > 
> > > XHTML Document...
> > > 
> > > <?xml version="1.0" encoding="utf-8"?>
> > > <html xmlns="http://www.w3.org/1999/xhtml";>
> > >     <head>
> > >         <meta name="generator" content="HTML Tidy, see
> > www.w3.org"/>
> > >         <title>The Title Is</title>
> > >     </head>
> > >     <body>
> > >         <ul id="bar">
> > >             <li/>
> > >             <li>foo<br/> after break <div/> after empty div</li>
> > >             <li>bar<strong>baz</strong></li>
> > >         </ul>
> > >         <ol>
> > >             <li>Item 1</li>
> > >             <li>Item 2</li>
> > >         </ol>
> > >         <p><span>foo</span><br/> asdf <b>bold another</b>
> > >             and <strong>a strong item</strong>
> > >         </p>
> > >         <div>
> > >             Content of a <b>div tag</b> here.
> > >             <ul>
> > >                 <li>
> > >                     Nested List Item 1
> > >                 </li>
> > >                 <li>
> > >                     Nested List Item 2
> > >                 </li>
> > >             </ul>
> > >             Now list is done
> > >         </div>
> > >     </body>
> > > </html>
> > > 
> > > Desired output...
> > > <?xml version="1.0" encoding="utf-8"?>
> > > <html xmlns="http://www.w3.org/1999/xhtml";>
> > >     <head>
> > >         <meta name="generator" content="HTML Tidy, see
> > www.w3.org"/>
> > >         <title><textnode>The Title Is</textnode></title>
> > >     </head>
> > >     <body>
> > >         <ul id="bar">
> > >             <li/>
> > >             <li><textnode>foo<br/> after break
> > > </textnode><div/><textnode> after empty div</textnode></li>
> > >             <li><textnode>bar<strong>baz</strong></textnode></li>
> > >         </ul>
> > >         <ol>
> > >             <li><textnode>Item 1</textnode></li>
> > >             <li><textnode>Item 2</textnode></li>
> > >         </ol>
> > >         <p><textnode><span>foo</span><br/> asdf <b>bold
> another</b>
> > >             and <strong>a strong item</strong></textnode>
> > >         </p>
> > >         <div>
> > >             <textnode>Content of a <b>div tag</b>
> here.</textnode>
> > >             <ul>
> > >                 <li>
> > >                     <textnode>Nested List Item 1</textnode>
> > >                 </li>
> > >                 <li>
> > >                     <textnode>Nested List Item 2</textnode>
> > >                 </li>
> > >             </ul>
> > >             <textnode>Now list is done</textnode>
> > >         </div>
> > >     </body>
> > > </html>
> > > 
> > > > -----Original Message-----
> > > > You're using XSLT 2.0 so this can be solved using grouping
> > > constructs.
> > > > 
> > > > Forget the templates that create <textnode> elements.
> > > > 
> > > > You want something like this, which causes adjacent 
> > > "inline" nodes to
> > > be
> > > > grouped under a new element, with a function to decide 
> > > whether a node
> > > is an
> > > > "inline" node:
> > > > 
> > > > <xsl:template match="div">
> 
=== message truncated ===


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

Current Thread