Reputation: 21
I need to check all elements to see if there is a preceding element (not always a sibling) that has any PI element. If so, I need to assign an attribute to all following elements UNTIL the next PI element is found.
Example XML Input:
<chapter id = "1">
<section>
<heading>some text here</heading>
<p>some text here<?Test1?></p>
</section>
<section>
<heading>some text here</heading>
<p>some text here<?Test2?></p>
</section>
</chapter>
<chapter id="2">
<section>
<p></p>
</section>
</chapter>
In this example, the chapter element with the id = "2" should get an attribute named "test2" and then stop (so it should not also get "test1".
What I have now:
<xsl:key name="test1PIs" match="*[not(self::main|self::title)]/processing-instruction('test1')" use="following::*/@id"/>
<xsl:key name="test2PIs" match="*[not(self::main|self::title)]/processing-instruction('test2')"
use="following::*/@id"/>
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:if test="key('test1PIs',@id)">
<xsl:attribute name="test1"/>
</xsl:if>
<xsl:if test="key('test2PIs',@id)">
<xsl:attribute name="test2"/>
</xsl:if>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
What I end up with:
<chapter id="2" test1="" test2="">
**child elements here**
</chapter>
What I really want:
<chapter id="2" test2="">
**child elements here**
</chapter>
@Michael Kay's response got me where I needed to be. In final:
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:variable name="piParent"
select="preceding::processing-instruction()[1]"/>
<xsl:if test="$piParent">
<xsl:attribute name="processPI">
<xsl:value-of select="name($piParent)"/>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
It works by assigning an attribute to all elements following a specific PI until it reaches another PI.
Upvotes: 0
Views: 44
Reputation: 163352
I think you want something like:
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:variable name="piParent"
select="preceding::*[processing-instruction()][1]"/>
<xsl:if test="$piParent">
<xsl:attribute name="name($piParent/processing-instruction())"/>
</xsl:if>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
However, I'm guessing a little because you haven't specified the task very clearly.
Upvotes: 1