467,915 Members | 1,823 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 467,915 developers. It's quick & easy.

XPath - How to query for <dd> elements ?

Imagine the XHTML "definition list" structure

<dl>
<dt>A</dt>
<dd>a</dd>

<dt>B</dt>
<dd>b1</dd>
<dd>b2</dd>

<dt>C</dt>

<dt>D</dt>
[ ...]
</dl>
Given the element containing "A" as the context node, how can I retrieve
the elements for "a", similarly "B" for "b1,b2" etc. ?

Using ./preceding-sibling::* [1] [self::dd]
I can retrieve the elements for "A" ("a") and "C" (an empty set)
However I can't see any way to get "b1" & "b2", just the first "b1"
Thanks for any advice

May 3 '06 #1
  • viewed: 3108
Share:
3 Replies
The simple-but-ugly way is to explicitly scan through the following
siblings until you hit the next <dt> or run out, using a recursive named
template.

Personally, I'd try to convince whoever was authoring the input document
to abandon the HTML markup on input (even if that's what you generate on
output) and use something with more structure to it, such as:

<deflist>
<entry><term>...</term><def>....</def><def>....</def></entry>
</deflist>

Then it's trivial; the definitions are the <def> children of the
<term>'s parent.

--
Joe Kesselman / Beware the fury of a patient man. -- John Dryden
May 3 '06 #2
Use
following-sibling::dd[preceding-sibling::dt[1]=current()]
get the following dd element whose first preceding dt is the surrent dt
element.
For instance the folllowing stylesheet
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="/">
<result>
<xsl:apply-templates select="//dt"/>
</result>
</xsl:template>

<xsl:template match="dt">
<for value="{.}">
<xsl:for-each

select="following-sibling::dd[preceding-sibling::dt[1]=current()]">
<got value="{.}"/>
</xsl:for-each>
</for>
</xsl:template>
</xsl:stylesheet>

will give you

<?xml version="1.0" encoding="utf-8"?>
<result>
<for value="A">
<got value="a"/>
</for>
<for value="B">
<got value="b1"/>
<got value="b2"/>
</for>
<for value="C"/>
<for value="D"/>
</result>

Note that the above assumes no namespace for the source elements, if
you use the XHTML namespace then you need to qualify the name tests
with the appropriate prefix, that is instead of dd for instance you
should have xhtml:dd and declare the XHTML namespace mapped to xhtml
prefix.

Best Regards,
George
---------------------------------------------------------------------
George Cristian Bina
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com

May 4 '06 #3
George Bina wrote:
following-sibling::dd[preceding-sibling::dt[1]=current()]
get the following dd element whose first preceding dt is the current dt
element.


.... Yep, that should work, and it's certainly more compact.

Performance of this vs. other solutions is going to depend on the exact
characteristics of your XSLT processor, and so is hard to predict
reliably. I'm not sure whether the one I've been using would recognize
the optimization opportunities in that expression or not; I should check.
--
() ASCII Ribbon Campaign | Joe Kesselman
/\ Stamp out HTML e-mail! | System architexture and kinetic poetry
May 4 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by The Plankmeister | last post: by
9 posts views Thread by Akseli Mški | last post: by
2 posts views Thread by AES/newspost | last post: by
4 posts views Thread by Andre Majorel | last post: by
1 post views Thread by enrico sabbadin | last post: by
13 posts views Thread by Mark | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.