xsl-list
[Top] [All Lists]

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

2006-02-26 18:42:17
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(_at_)saxonica(_dot_)com> 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 

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--