2015-03-11 8 views
1

У меня огромный мозговой пердит в течение последних двух дней. Мне нужно проверить, если первый <step1> дочернего элемент <proc> имеет предшествующие родственный <note>:XSL проверка непосредственно предшествующего брата

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

Я пытаюсь преобразовать <step1> элемент (и ребенок <step2> элементов) для <proceduralStep> элементов со следующим XSL и не имея какой-либо удачи в получении <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> элементов (или где-либо еще). Я создал пустой шаблон, чтобы запретить прок \ записку помещаются в моем выходе:

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

Я клянусь, что я делал это раньше, но я просто не вспоминая сегодня утром (или вчера утром по этому вопросу) ,

+2

ли с помощью 'предшествующих-родственного :: * [1] [само :: примечания]' вместо 'previous-sibling :: * [1] [note]' решить проблему? Это изменение будет реализовывать словесное описание «необходимо проверить, имеет ли первый дочерний элемент (сразу) предшествующий родственный брат ». –

+0

Это сделало. Я знал, что это то, что я видел/делал раньше, только в другом контексте. Я использую это для другого шаблона, только для следующего брата. Спасибо @ МартинХоннен. – twfurst

ответ

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

Благодарим за то, что я могу упростить свой код, и это изменит. – twfurst

Смежные вопросы