仅使用XSLT选择具有特定子项的最后一个(最近的)元素



我需要检查所有元素,看看是否有前面的元素(不总是同级元素(具有任何PI元素。如果是这样,我需要为以下所有元素分配一个属性UNTIL找到下一个PI元素。

示例XML输入:

<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>

在本例中,id为";2〃;应该得到一个名为"的属性;test2";然后停止(所以它不应该也得到"test1">

我现在拥有的:

<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>

我最终得到的是:

<chapter id="2" test1="" test2="">
**child elements here**
</chapter>

我真正想要的:

<chapter id="2" test2="">
**child elements here**
</chapter>

@Michael Kay的回应让我到达了我需要的地方。决赛:

<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>

它的工作方式是将一个属性指定给特定PI之后的所有元素,直到它到达另一个PI。

我想你想要这样的东西:

<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>

不过,我有点猜测,因为您没有非常清楚地指定任务。

相关内容

最新更新