在嵌套元素的XSLT处理中苦苦挣扎

时间:2014-11-17 14:17:11

标签: html xslt nested

我正在尝试将一些嵌套元素的XML处理成HTML,其中每个处理过的元素都在标记内,这样我就可以根据用户按下Next链接使用JavaScript显示和隐藏div。我遇到了问题,因为父母的标签被放置在2个孩子之后。这导致了一个问题,因为我无法隐藏父母来显示孩子。

这是我开始使用的XML代码段:

<mainProcedure>
   <proceduralStep id="pstp1">
      <para>Some text to display 1</para>
   </proceduralStep>
   <proceduralStep id="pstp2">
      <note>Warning Note to display</note>
      <para>Some text to display 2</para>
      <proceduralStep id="pstp21">
         <para>Nested procedural step 1</para>
      </proceduralStep>
      <proceduralStep id="pstp22">
         <para>Nested procedural step 2</para>
      </proceduralStep>
   </proceduralStep>
   <proceduralStep id="pstp3">
      <para>Some text to display 3</para>
   </proceduralStep>
</mainProcedural>

可以嵌套。我当前的XSLT处理它的方式是在关闭后放置标记。我相信我需要在输出时展平这个结构,以便JavaScript显示和隐藏标签正常工作。所以没有:

<div id="pstp1">  Some text to display 1 
   NEXT (embeds JS to hide pstp1 and show pstp2)   
</div>
<div id="pstp2"> 
   NOTE: Warning Note to display
   Some text to display 1
      NEXT (embeds JS to hide pstp2 and show pstp21)   
   <div id="pstp21>Nested procedural step 1
      NEXT (embeds JS to hide pstp21 and show pstp22)   
   </div>
   <div id="pstp22>Nested procedural step 2
      NEXT (embeds JS to hid pstp22 and show pstp3)
   </div>
</div>
<div id="pstp3"> Some test to display 3 </div>

我相信为了显示和隐藏div才能正常工作我需要将输出压平为:

<div id="pstp1">  
   Some text to display 1 
   NEXT (embeds JS to hide pstp1 and show pstp2)   
</div>
<div id="pstp2"> 
   NOTE: Warning Note to display
   Some text to display 1
   NEXT (embeds JS to hide pstp2 and show pstp21)   
</div>
<div id="pstp21>
   Nested procedural step 1
   NEXT (embeds JS to hide pstp21 and show pstp22)   
</div>
<div id="pstp22>
   Nested procedural step 2
   NEXT (embeds JS to hid pstp22 and show pstp3)
</div>
<div id="pstp3"> Some test to display 3 </div>

我无法弄清楚如何做到这一点。我在我的XSLT中有一个,所以这是在第二个元素上调用的,第二个元素是在处理嵌套元素后显示的。

以下是用于处理元素的当前XSLT模板。请注意,这是一项正在进行的工作,我可能会复杂一些不必要的东西。如果模板上有任何问题以及我为什么要做某事,请告诉我。

<xsl:template match="proceduralStep">
    <xsl:choose>
       <!--  See if there is a child proceduralStep (or a nested proceduralStep) -->
       <xsl:when test="child::proceduralStep">
          <!-- procedrualStep contains a nested proceduralStep, count the precdeing siblings to help with numbering of steps -->
          <xsl:variable name="stepCounter" select="count(preceding-sibling::proceduralStep)+1" />
          <xsl:variable name="step_id" select="./@id" />              
          <xsl:variable name="nextRefId" select="child::proceduralStep/@id" />

          <xsl:choose>
             <xsl:when test="$stepCounter = 1">
                <div id="{$step_id}" style="display: block;">
                   Step <xsl:value-of select="$stepCounter" />
                   <xsl:text> </xsl:text>
                   <xsl:apply-templates /> 
                   <br/>
                   <div>
                      <a href="#{$nextRefId}" onclick="show_hide_div('{$step_id}','{$nextRefId}')">Next</a><br/>
                   </div>              
                </div>                
             </xsl:when>
             <xsl:otherwise>
                <div id="{$step_id}" style="display: none;">
                      Step <xsl:value-of select="$stepCounter" />
                      <xsl:text> </xsl:text>
                      <xsl:apply-templates />
                 </div>
              </xsl:otherwise>
          </xsl:choose>

       </xsl:when>
       <xsl:otherwise>
          <!-- <proceduralStep> element does not have any nested <proceduralStep> elements  -->

          <!-- Count the number of preceding <proceduralStep> elements  -->
          <xsl:variable name="stepCounter" select="count(preceding-sibling::proceduralStep)+1"/> 

          <!-- Get the current <proceduralStep> element's id  -->                     
          <xsl:variable name="step_id" select="./@id"/>

          <!-- Since the current <proceduralStep> does not have any children, get the following <proceduralStep> sibling id -->
          <xsl:variable name="nextRefId" select="following-sibling::proceduralStep/@id"/>

          <xsl:choose>
             <!-- If this is the first <proceduralStep> element create the <div>  -->
             <xsl:when test="$stepCounter = 1">

                <!-- first time encountering a step, check to see if it is the first nested <proceduralStep> -->
                <xsl:choose>
                   <xsl:when test="parent::proceduralStep">
                      <!-- add the Next button before we output the <proceduralStep> -->
                      <div>
                         <xsl:variable name="parentProcStepId" select="parent::proceduralStep/@id" />
                         <p>parentProcStepID: <xsl:value-of select="$parentProcStepId" /> </p>
                         <a href="#{$step_id}" onclick="show_hide_div('{$parentProcStepId}','{$step_id}')">Next</a><br/>
                      </div>

                      <div id="{$step_id}" style="display: none;">
                         Step <xsl:value-of select="$stepCounter" />
                         <xsl:text> </xsl:text>
                         <xsl:apply-templates />
                         <br/>
                         <div>
                            <a href="#{$nextRefId}" onclick="show_hide_div('{$step_id}','{$nextRefId}')">Next</a><br/>
                         </div>
                      </div>      
                   </xsl:when>
                   <xsl:otherwise>
                      <div id="{$step_id}" style="display: block;">
                         Step <xsl:value-of select="$stepCounter" />
                         <xsl:text> </xsl:text>
                         <xsl:apply-templates />
                         <br/>

                         <div>
                            <a href="#{$nextRefId}" onclick="show_hide_div('{$step_id}','{$nextRefId}')">Next</a><br/>
                         </div>
                      </div>
                      </xsl:otherwise>
                      </xsl:choose>


             </xsl:when>
              <xsl:otherwise>
                 <!-- do nothing -->
             </xsl:otherwise>
          </xsl:choose>      
       </xsl:otherwise>
   </xsl:choose>
</xsl:template>

知道如何帮助实现这一目标吗?

谢谢

1 个答案:

答案 0 :(得分:0)

这样怎么样:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/*">
    <root>
        <xsl:apply-templates select="proceduralStep"/>
    </root>
</xsl:template>

<xsl:template match="proceduralStep">
    <div id="{@id}">
        <xsl:apply-templates select="note | para"/>
        <br/>   
        <xsl:text>NEXT( ... )</xsl:text>
    </div>
    <xsl:apply-templates select="proceduralStep"/>
</xsl:template>

<xsl:template match="note">
    <xsl:text>NOTE: </xsl:text>
    <xsl:value-of select="."/>
    <br/>   
</xsl:template>

</xsl:stylesheet>