|
Subject: Re: [xsl] sequential navigation problem (long) From: Jakob.Fix@xxxxxxxxxxxxxxxxx Date: Thu, 5 Dec 2002 17:30:54 +0100 |
Jeni, David,
Thanks for your responses. Thanks for pointing out the error in my logic.
I am currently using the catch-all expressions, which works ok,
(ancestor::* | preceding::*)
[self::PART or self::CHAP or self::SECT or self::ART or
self::SYMBOLS or self::APPENDIX or self::SART][@ID][last()]
and
(descendant::* | following::*)
[self::PART or self::CHAP or self::SECT or self::ART or
self::SYMBOLS or self::APPENDIX or self::SART][@ID][1]
However, as you indicated, this slows down the processing enormously:
normally, to fragment my 15 MB file into about 1800 fragments, it takes
about 8 minutes. Currently, I am at 1040 fragments processed in 90 minutes
... another 800 to go ...
An occasion to optimize ...
I will also look into the function extension to modularize the stylesheet.
Again, thanks for your quick replies!
Jakob.
Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>@lists.mulberrytech.com on 12/05/2002
01:26:52 PM
Veuillez répondre à xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Envoyé par : owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Pour : Jakob Fix/HO/VERITAS@VERITAS
cc : xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Objet : Re: [xsl] sequential navigation problem (long)
Ref. Message:
Hi Jakob,
> In addition to the parent/next/prev sibling navigation, I want to add
> sequential (in the book, page flicker sense) navigation as well, so that
it
> becomes possible to navigate the complete document only using "Next
> fragment" or "Previous fragment" buttons. So, basically every fragment
> must know the ID of the sequentially preceding and following fragment.
>
> For this I have defined the following algorithms:
>
> for previous fragment:
> 1) test: node's left sibling has a last child with a known GI and an
> ID
> attr
> 2) else test: node has a left sibling with a known GI and an ID attr
> 3) else test: node has a parent with a known GI and an ID attr
>
> for next fragment:
> 1) test: node has a first child with a known GI and an ID attr
> 2) else test: node has sibling with a known GI and an ID attr
> 3) else test: node's parent has a sibling with a known GI and an ID attr
These tests miss out situations where, for example, you want the next
fragment from a fragment whose parent doesn't have a following
sibling but whose grandparent (or other ancestor) does.
Rather than going through these separate tests, you might find it
better to use the ancestor/descendant and preceding/following axes.
For the previous fragment, you could use:
(ancestor::* | preceding::*)
[self::PART or self::CHAP or self::SECT or self::ART or
self::SYMBOLS or self::APPENDIX or self::SART][@ID][last()]
and for the next fragment, you could similarly use:
(descendant::* | following::*)
[self::PART or self::CHAP or self::SECT or self::ART or
self::SYMBOLS or self::APPENDIX or self::SART][@ID][1]
Using preceding and following will probably have an impact on the
speed of the transformation, but you said you don't care too much
about that -- try it and see.
> where a "known GI" is one in this list (this is to avoid fragmenting
> items such as notes and subsections which won't have their own
> fragment, but have an ID nevertheless): "PART, CHAP, SECT, ART,
> SYMBOLS, APPENDIX, SART"
>
> I have defined two named templates "tpl.next.fragment" and
> "tpl.prev.fragment" which are called from the template responsible for
> fragmenting, and are supposed to "return" the ID. Thus, the current node
> is available in these templates. Please note, these templates are not
yet
> tested.
>
> My problem now is that I am not sure how to efficiently and
> concisely write the XPath test expression of what is defined in the
> algorithms. The following shows my approach, not tested.
Your approach won't work, unfortunately, because you're holding the
list of known GIs in a *string* and then trying to evaluate that
string as part of an XPath expression. Actually, even if that did
work, the expression that it would create wouldn't be a legal one...
The easiest way to make your list of known.gis extensible with XSLT
1.0 is to store it in an entity:
<!DOCTYPE xsl:stylesheet [
<!ENTITY known.gis
'self::PART or self::CHAP or self::SECT or self::ART or
self::SYMBOLS or self::APPENDIX or self::SART'>
]>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
...
<xsl:template name="tpl.next.fragment">
<xsl:choose>
<!-- does this node have a FIRST CHILD
with an ID value and
one of the GIs above? -->
<xsl:when test="child::*[&known.gis;][@ID][1]">
</xsl:when>
<!-- does this node have a FOLLOWING SIBLING
with an ID value
and one of the GIs above? -->
<xsl:when test="following-sibling::*[&known.gis;][@ID][1]">
</xsl:when>
<!-- does this node's PARENT DOES HAVE A NEXT SIBLING
with an
ID value and one of the GIs above? -->
<xsl:when test="../following-sibling::*[&known.gis;][@ID]">
</xsl:when>
<!-- not interested -->
<xsl:otherwise/>
</xsl:choose>
</xsl:template>
...
</xsl:stylesheet>
If you're using a processor that supports func:function from EXSLT
(e.g. Saxon or Xalan) and you're happy to use it, then I'd recommend
writing a function that tests whether a given node is one of your
known GIs or not, and then calling that function, as follows:
<func:function name="my:is-known-GI">
<xsl:param name="n" />
<func:result
select="$n/self::PART or $n/self::CHAP or $n/self::SECT or
$n/self::ART or $n/self::SYMBOLS or $n/self::APPENDIX or
$n/self::SART" />
</func:function>
<xsl:template name="tpl.next.fragment">
<xsl:choose>
<!-- does this node have a FIRST CHILD
with an ID value and
one of the GIs above? -->
<xsl:when test="child::*[my:is-known-GI(.)][@ID][1]">
</xsl:when>
<!-- does this node have a FOLLOWING SIBLING
with an ID value
and one of the GIs above? -->
<xsl:when test="following-sibling::*[my:is-known-GI(.)][@ID][1]">
</xsl:when>
<!-- does this node's PARENT DOES HAVE A NEXT SIBLING
with an
ID value and one of the GIs above? -->
<xsl:when test="../following-sibling::*[my:is-known-GI(.)][@ID]">
</xsl:when>
<!-- not interested -->
<xsl:otherwise/>
</xsl:choose>
</xsl:template>
I hope that gives you some ideas.
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| Re: [xsl] sequential navigation pro, Joerg Heinicke | Thread | Re: [xsl] sequential navigation pro, David Carlisle |
| Re: [xsl] qualitative decline of xs, Wendell Piez | Date | [xsl] A general <xsl:key> question., Edward L. Knoll |
| Month |