过去两天我的脑屁很大。我需要检查<step1>
的第一个<proc>
子元素是否有<note>
的前一个兄弟:
<proc>
<note>
<trim.para>Some sort of note</trim.para>
</note>
<step1>
<para>Turn off all electrical power .</para>
</step1>
<step1>
<para>A second step.</para>
</step1>
</proc>
我正在尝试使用以下XSL将<step1>
元素(和子<step2>
元素)转换为<proceduralStep>
元素,并且没有任何运气让<note>
成为包括:
<xsl:template match="step1 | step2">
<!-- create key/value pair to store existing ids with new value for proceduralStep element-->
<xsl:choose>
<xsl:when test="./@id">
<proceduralStep id="{@id}">
<xsl:if test="preceding-sibling::*[1][note]">
<xsl:for-each select="preceding-sibling::*[1][note]">
<note>
<notePara>
<xsl:value-of select="./trim.para"/>
</notePara>
</note>
</xsl:for-each>
</xsl:if>
<xsl:apply-templates/>
</proceduralStep>
</xsl:when>
<xsl:otherwise>
<proceduralStep>
<xsl:if test="preceding-sibling::*[1][note]">
<xsl:for-each select="preceding-sibling::*[1][note]">
<note>
<notePara>
<xsl:value-of select="./trim.para"/>
</notePara>
</note>
</xsl:for-each>
</xsl:if>
<xsl:apply-templates/>
</proceduralStep>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
输出:
<mainProcedure>
<proceduralStep>
<para>Turn off all electrical power.</para>
</proceduralStep>
<proceduralStep>
<para>A second step.</para>
</proceduralStep>
</mainProcedure>
我需要输出:
<mainProcedure>
<proceduralStep>
<note>
<notePara>Some sort of note</notePara>
</note>
<para>Turn off all electrical power.</para>
</proceduralStep>
<proceduralStep>
<para>A second step.</para>
</proceduralStep>
</mainProcedure>
我已经有一个模板可以在<note>
或<step1>
元素(或其他任何地方)内部处理<step2>
元素时处理它们。我创建了一个空模板来禁止将proc \ note放在我的输出中:
<xsl:template match="note[parent::proc]"></xsl:template>
<xsl:template match="note">
<note>
<xsl:apply-templates/>
</note>
</xsl:template>
<xsl:template match="note/trim.para">
<notePara>
<xsl:apply-templates/>
</notePara>
</xsl:template>
我发誓我以前做过这件事,但我今天早上(或昨天上午就此事)没有回忆起来。
答案 0 :(得分:1)
正如马丁在评论中所说,你需要使用self::
轴来检查前面的兄弟。您还可以删除if
,并通过复制现有的id
属性来显着减少代码重复:
<xsl:template match="step1 | step2">
<!-- create key/value pair to store existing ids with new value for proceduralStep
element-->
<proceduralStep>
<!-- copy id attribute from step1|step2 if it exists, do nothing if not -->
<xsl:copy-of select="@id" />
<!-- no need for an if here - if the immediately preceding sibling is not a
note then the select will return an empty node set, which makes the
for-each a no-op -->
<xsl:for-each select="preceding-sibling::*[1][self::note]">
<note>
<notePara>
<xsl:value-of select="./trim.para"/>
</notePara>
</note>
</xsl:for-each>
<xsl:apply-templates/>
</proceduralStep>
</xsl:template>