【问题标题】:XSL check immediate preceding siblingXSL 检查紧接在前的同级
【发布时间】:2015-05-13 03:15:18
【问题描述】:

在过去的两天里,我脑子里放了一个大屁。我需要检查<proc> 的第一个<step1> 子元素是否有<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 将 &lt;step1&gt; 元素(和子 &lt;step2&gt; 元素)转换为 &lt;proceduralStep&gt; 元素,但没有任何运气将 &lt;note&gt; 包含在内:

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

&lt;note&gt; 元素出现在&lt;step1&gt;&lt;step2&gt; 元素(或其他任何地方)内部时,我已经有一个模板来处理它们。我创建了一个空模板来禁止将 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>

我发誓我以前做过,但今天早上(或者昨天早上)我不记得了。

【问题讨论】:

  • 使用preceding-sibling::*[1][self::note] 代替preceding-sibling::*[1][note] 能解决问题吗?该更改将实现口头描述“需要检查 的第一个 子元素是否具有(立即)前面的 兄弟”。
  • 做到了。我知道这是我以前见过/做过的事情,只是在不同的背景下。我将它用于另一个模板,仅用于跟随兄弟。谢谢@MartinHonnen。

标签: xml xslt


【解决方案1】:

正如 Martin 在他的评论中建议的那样,您需要使用 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>

【讨论】:

  • 感谢您指出如何简化我的代码,我也会对此进行更改。
猜你喜欢
  • 1970-01-01
  • 2012-07-20
  • 2012-11-30
  • 2017-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-07
  • 1970-01-01
相关资源
最近更新 更多