Keys: selecting last child of a preceding-sibling node

Ryeppiavo

New Member
I have some (malformed DITA) XML in the following format:\[code\]<dl><dlentry><dt>BLARG</dt><dd>BLARG Definition</dd><dt>BLARG2</dt><dd>BLARG2 Definition</dd></dlentry></dl><dl><dlentry><dt>BLARG3</dt><dd>BLARG3 Definition</dd></dlentry></dl><p>Continuation of BLARG3 definition.</p><note>Note pertaining to BLARG3 definition</note>\[/code\]and so on.What I am trying to do is consolidate this series of \[code\]<dl>\[/code\] elements into a single \[code\]<dl>\[/code\], which would look like this:\[code\]<dl> <dlentry><dt>BLARG</dt> <dd>BLARG Definition</dd></dlentry> <dlentry><dt>BLARG2</dt> <dd>BLARG2 Definition</dd></dlentry> <dlentry><dt>BLARG3</dt> <dd>BLARG3 definition. Continuation of BLARG3 definition. <note>Note pertaining to BLARG3 definition</note></dd></dlentry><dl>\[/code\]I am trying to use keys to index any \[code\]<p>\[/code\] or \[code\]<note>\[/code\] nodes according to the \[code\]generate-id()\[/code\] value of the preceding \[code\]<dd>\[/code\], like this:\[code\]<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"version="1.0"><xsl:key name="kFollowing" match="p|note|table" use="generate-id(preceding::dd[1])"/> <!-- identity template --><xsl:template match="@*|node()" name="identity"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy></xsl:template><xsl:template match="dl"> <xsl:choose> <xsl:when test="count(preceding::dl)=0"> <!--We only want to process the first dl. All others should be ignored, because their content will get included in this one.--> <dl> <!--Want to grab all following terms, except ones that contain phrase elements, which need to be turned into a table because they are field values--> <xsl:for-each select="following::dt[not(child::ph)]|descendant::dt"> <dlentry><dt><xsl:value-of select="normalize-space(.)"/></dt> <xsl:variable name="ddID"><xsl:value-of select="generate-id(following::dd[1])"/></xsl:variable> <dd><xsl:for-each select="following::dd[1]"> <xsl:apply-templates/><xsl:text>. </xsl:text> </xsl:for-each> <xsl:variable name="ddKey" select="key('kFollowing',generate-id(following::dd[1]))"/> <xsl:for-each select="following::*[$ddKey]"> <xsl:apply-templates/></xsl:for-each> </dd> </dlentry> </xsl:for-each> </dl> </xsl:when> <xsl:otherwise/> </xsl:choose></xsl:template>\[/code\]
 
Back
Top