Trevor,
David has suggested how you can use brute-force XPath for this sort
of test. In XSLT 1.0, keys can also make things just a touch easier:
<xsl:key name="textcontent-by-id" use="generate-id()"
match="text()[normalize-space()] | em | sub | sup"/>
(Only text nodes that have non-whitespace content are returned by
this key, to avoid problems with cosmetic whitespace. If you have
clean whitespace stripping you can remove the normalize-space() predicate.)
<xsl:key name="blockcontent-by-id" use="generate-id()"
match="para | note | warning | table | img | define | list | ul | ol"/>
Then in an appropriate context:
<xsl:template match="answer">
<xsl:choose>
<xsl:when test="node()[key('textcontent-by-id',generate-id()] and
node()[key('blockcontent-by-id',generate-id()]">
... both textcontent and blockcontent children exist ...
</xsl:when>
<xsl:when test="node()[key('textcontent-by-id',generate-id()]">
... textcontent children exist ...
</xsl:when>
<xsl:when test="node()[key('blockcontent-by-id',generate-id()]">
... blockcontent children exist ...
</xsl:when>
<xsl:otherwise>
... any children are in neither set
(if the XML is valid there are no children) ...
</xsl:otherwise>
</xsl:choose>
</xsl:template>
This works because a node will be returned by the key only if it
matches the pattern in the key declaration. As you recall, a node-set
with members in it tests "true" and one with none tests "false", so
the expression "key('blockcontent-by-id',generate-id()" returns true
only if the node that provides the ID (the context node for the
expression) is one of the node types matched in the declaration.
It's probably no clearer to the neophyte than brute force, and may be
a tiny bit slower, but it is a bit easier to maintain, because it
encapsulates the logic of your content models somewhat in your key
declarations.
The other part of your problem, the wrapping of consecutive
non-blockcontent child nodes in divs, is actually rather harder in
XSLT 1.0, though not impossible. (But it's fairly straightforward in
2.0, which you should know.) Indeed, a solution for this problem can
also make the problem you've just asked about go away ... instead of
distinguishing between three types of parents (ones containing
blocks, ones containing text content, and ones with a mix), you just
pick up all the children and process them with the necessary grouping logic.
Cheers,
Wendell
At 09:02 AM 7/4/2007, you wrote:
I have the following element definition (I've cut it down slightly for
reasons of space but the principle is clear):
<!ENTITY % simple "#PCDATA">
<!ENTITY % markup "em|sub|sup">
<!ENTITY % textcontent "%simple;|%markup;">
<!ENTITY % lists "define|list|ul|ol">
<!ENTITY % blockcontent "para|note|warning|table|img|%lists;">
<!ENTITY % complexcontent "%textcontent;|%blockcontent;">
<!ELEMENT answer (%complexcontent;)*>
I am writing an XSL transform to output HTML, and the template for <answer>
needs to take into consideration whether
a) all the children of answer are textcontent;
b) all the children of answer are blockcontent;
c) there is a mixture of textcontent and blockcontent children
So my first question is: how could I write these tests in XSL 1?
In the output HTML an <answer> element is going to generate a <div>, and
case (a) will require a <div><p>...</p></div>, while in case (b) a simple
<div>...</div> will suffice.
Case (c) is evidence of a poorly structured document, but the XML is defined
by/validated against a DTD not a schema and so I live with the possibility.
This will require my stylesheet to generate <div>...</div> while wrapping
any sequences of consecutive 'textcontent' children in a <p>...</p>.
That leads to the second question: is there a construct that will do this,
comprehensible by a bear with very little brain, again in XSL 1?
Thanks if you can help
Cheers
Trevor
--~------------------------------------------------------------------
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>
--~--
======================================================================
Wendell Piez
mailto:wapiez(_at_)mulberrytech(_dot_)com
Mulberry Technologies, Inc. http://www.mulberrytech.com
17 West Jefferson Street Direct Phone: 301/315-9635
Suite 207 Phone: 301/315-9631
Rockville, MD 20850 Fax: 301/315-8285
----------------------------------------------------------------------
Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================
--~------------------------------------------------------------------
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>
--~--