挣扎于嵌套元素的 XSLT 处理 [英] Struggling with XSLT processing of nested elements

查看:49
本文介绍了挣扎于嵌套元素的 XSLT 处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这是我开始使用的 XML 片段:

<proceduralStep id="pstp1"><para>一些要显示的文本 1</para></proceduralStep><proceduralStep id="pstp2"><note>要显示的警告提示</note><para>一些要显示的文本 2</para><proceduralStep id="pstp21"><para>嵌套程序步骤1</para></proceduralStep><proceduralStep id="pstp22"><para>嵌套的程序步骤 2</para></proceduralStep></proceduralStep><proceduralStep id="pstp3"><para>一些要显示的文本 3</para></proceduralStep></mainProcedural>

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

一些要显示的文本 1NEXT(嵌入JS隐藏pstp1,显示pstp2)

<div id="pstp2">注意:要显示的警告注意事项一些要显示的文本 1NEXT(嵌入JS隐藏pstp2并显示pstp21)<div id="pstp21>嵌套程序步骤 1NEXT(嵌入JS隐藏pstp21,显示pstp22)

<div id="pstp22>嵌套程序步骤 2NEXT(嵌入 JS 以隐藏 pstp22 并显示 pstp3)

<div id="pstp3">一些测试显示 3 </div>

我相信为了显示和隐藏 div 正常工作,我需要将输出展平到:

一些要显示的文本 1NEXT(嵌入JS隐藏pstp1,显示pstp2)

<div id="pstp2">注意:要显示的警告注意事项一些要显示的文本 1NEXT(嵌入JS隐藏pstp2并显示pstp21)

<div id="pstp21>嵌套程序步骤 1NEXT(嵌入JS隐藏pstp21,显示pstp22)

<div id="pstp22>嵌套程序步骤 2NEXT(嵌入 JS 以隐藏 pstp22 并显示 pstp3)

<div id="pstp3">一些测试显示 3 </div>

我不知道如何做到这一点.我的 XSLT 中有一个,因此在第二个元素上调用它,第二个元素在处理嵌套元素后显示.

这是用于处理元素的当前 XSLT 模板.请注意,这是一项正在进行的工作,我可能将一些不必要的事情复杂化了.如果对模板有任何疑问以及我为什么要这样做,请告诉我.

<!-- 查看是否有子proceduralStep(或嵌套proceduralStep)--><xsl:when test="child::proceduralStep"><!-- procedrualStep 包含一个嵌套的 proceduralStep,计算前面的兄弟以帮助编号步骤 --><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:when test="$stepCounter = 1"><div id="{$step_id}" style="display: block;">步骤 <xsl:value-of select="$stepCounter"/><xsl:text></xsl:text><xsl:apply-templates/><br/><div><a href="#{$nextRefId}" onclick="show_hide_div('{$step_id}','{$nextRefId}')">下一步</a><br/>

</xsl:when><xsl:否则><div id="{$step_id}" style="display: none;">步骤 <xsl:value-of select="$stepCounter"/><xsl:text></xsl:text><xsl:apply-templates/>

</xsl:否则></xsl:选择></xsl:when><xsl:否则><!-- <proceduralStep>元素没有任何嵌套的 <proceduralStep>元素 --><!-- 计算前面<proceduralStep>的数量元素 --><xsl:variable name="stepCounter" select="count(preceding-sibling::proceduralStep)+1"/><!-- 获取当前的 <proceduralStep>元素的 id --><xsl:variable name="step_id" select="./@id"/><!-- 由于当前的 <proceduralStep>没有任何孩子,获得以下<proceduralStep>兄弟ID --><xsl:variable name="nextRefId" select="following-sibling::proceduralStep/@id"/><!-- 如果这是第一个 <proceduralStep>元素创建<div>--><xsl:when test="$stepCounter = 1"><!-- 第一次遇到step,查看是否是第一个嵌套的--><xsl:when test="parent::proceduralStep"><!-- 在我们输出 <proceduralStep> 之前添加 Next 按钮.--><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}')">下一步</a><br/>

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

</xsl:when><xsl:否则><div id="{$step_id}" style="display: block;">步骤 <xsl:value-of select="$stepCounter"/><xsl:text></xsl:text><xsl:apply-templates/><br/><div><a href="#{$nextRefId}" onclick="show_hide_div('{$step_id}','{$nextRefId}')">下一步</a><br/>

</xsl:否则></xsl:选择></xsl:when><xsl:否则><!-- 什么都不做--></xsl:否则></xsl:选择></xsl:否则></xsl:选择></xsl:模板>

知道如何帮助它发挥作用吗?

谢谢

解决方案

这种方式怎么样:

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/><xsl:template match="/*"><根><xsl:apply-templates select="proceduralStep"/></root></xsl:模板><xsl:template match="proceduralStep"><div id="{@id}"><xsl:apply-templates select="note | para"/><br/><xsl:text>NEXT( ... )</xsl:text>

<xsl:apply-templates select="proceduralStep"/></xsl:模板><xsl:template match="note"><xsl:text>注意:</xsl:text><xsl:value-of select="."/><br/></xsl:模板></xsl:stylesheet>

I am trying to process some XML that has nested elements into HTML where each processed element is within tags so that I can show and hide divs using JavaScript based on the user pressing a Next link. I am having problems because the tag for the parent is being placed after the for the 2 children. This is causing an issue because I cannot hide the parent to show the children.

here is the XML snippet I am starting with:

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

The can be nested. The way my current XSLT is processing this is that the tag for is placed after the closing for . I believe I need to flatten this structure when I output so the JavaScript showing and hiding of tags works properly. So instead of having:

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

I believe in order to the show and hide div to work properly I need to flattened the output to:

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

I cannot figure out how to do this. I have an in my XSLT so then this is invoked on the second element, the for the second element is showing up after the processing of the nested elements.

Here is the current XSLT template used to process the element. Please note that this is a work in progress and I may have complicated something that was not necessary. If there are any questions on the template and why I did something, please let me know.

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

Any idea how to help get this to work?

Thank you

解决方案

How about this way:

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

这篇关于挣扎于嵌套元素的 XSLT 处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆