Jarek Mazur
Jarek Mazur

Reputation: 2072

Select nodes that have specific descendants

I have an xhtml page containing multiple divs. This:

 <xsl:template match="div[@class = 'toc']">

selects divs that interest me (all of them contain unordered lists - ul). Now I would like to select only those divs that contain two levels of ul elements.

In general: how do I select nodes that have specific type of children?

I tried something like this:

<xsl:apply-templates select="body/div[@class = 'toc']/ul/li/ul" />

                   ...

<xsl:template match="div[@class = 'toc']/ul/li/ul">    
  <xsl:apply-templates mode="final_template" select="../../.."/> 
</xsl:template>

<xsl:template name="final_template" match="div">
        ...
</xsl:template>

But it doesn't work. What is more I believe there must be a cleaner approach to this problem than mine.

Upvotes: 2

Views: 899

Answers (1)

JLRishe
JLRishe

Reputation: 101662

In general, to select nodes that have certain children:

NodeToSelect[childName]

To select nodes that have certain descendants:

NodeToSelect[.//descendantName]

Please try this path for your situation:

div[@class = 'toc'][.//ul//ul]

For the XSLT, this is probably a good way to go:

<xsl:apply-templates select="body/div[@class = 'toc'][.//ul//ul]" mode="twoUlDescendants" />

                   ...

<xsl:template match="div" mode="twoUlDescendants">    
   <!-- Work with div here. -->
</xsl:template>

You can change the name of the mode "twoUlDescendants" to something that more accurately describes the purpose of these particular divs.

Upvotes: 2

Related Questions