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 00:27:49 -0800 (PST) |
Great news. I finally solved this problem. It was a combination of issues. Incorrect match criteria and missing nested <xsl:apply-templates/> call. I do have one follow up question. If you all think I should make this a different post just let me know. 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? 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(.)" > > > > > > 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> > > > > > === message truncated === __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Problems with mixed conte, Tony Kinnis | Thread | RE: [xsl] Problems with mixed conte, Michael Kay |
[xsl] Sort of footnote nodes, proce, Trevor Nicholls | Date | RE: [xsl] Problems with mixed conte, Tony Kinnis |
Month |