Subject: RE: 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
|