0

我需要帮助来设置一个有效的 XSLT 条件:在贯穿问题节点的 for-each 循环中;如果节点 A 的条件有效,则在节点 B 中显示详细信息。 XML 示例:

<Survey>
    <questions>
        <Number>1.0</Number>
        <Question>Was the show good?</Question>
        <Answer>Yes/No</Answer>
        <Details>N/A</Details>
    </questions>
    <questions>
        <Number>1.1</Number>
        <Question>Explain why</Question>
        <Answer>N/A</Answer>
        <Details>The actors were good</Details>
    </questions>
    <questions>
        <Number>2.0</Number>
        <Question>Was the food good?</Question>
        <Answer>Yes|No</Answer>
        <Details>N/A</Details>
    </questions>
    <questions>
        <Number>2.1</Number>
        <Question>Provide details</Question>
        <Answer>N/A</Answer>
        <Details>The pasta was too salty</Details>
    </questions>
</Survey>

我需要的是仅使用for-each的循环如果问题编号= 1.0和答案='是',仅在问题编号1.1中显示详细信息如果问题编号= 2.0并且答案='否',则在问题编号2.1中显示详细信息

我已经尝试了所有方法,例如 if,for each,choose/when,但它没有奏效。我检查了你的其他帖子,但找不到类似的东西。谢谢你,图比。

我很抱歉,所以它应该是这样的:

    <Survey>     
        <questions>
            <Number>1.0</Number>
            <Question>Was the show good?</Question>
            <Answer>Yes</Answer>
            <Details>N/A</Details>     
    </questions>     
    <questions>
         <Number>1.1</Number>
         <Question>Explain why</Question>
         <Answer>N/A</Answer>         
         <Details>The actors were good</Details>
     </questions>     
     <questions>
         <Number>2.0</Number>
         <Question>Was the food good?</Question>         
         <Answer>Yes</Answer>
         <Details>N/A</Details>
     </questions>
     <questions>
         <Number>2.1</Number>
         <Question>Provide details</Question>
         <Answer>N/A</Answer>
         <Details>The pasta was too salty</Details>
     </questions>
 </Survey> 

这是我的一段代码:(对不起,它实际上是别人的代码。当上一个问题具体回答“是”或“否”时,我需要修改显示下一个问题的部分

<fo:table-body start-indent="0pt">
    <xsl:for-each select="../Survey">
        <xsl:for-each select="questions">
        <xsl:sort select="Number" data-type="number" order="ascending"/>
            <fo:table-row>
                <xsl:choose>
                    <xsl:when test="ends-with(Number,'0')">
                        <fo:table-cell border="solid 1pt gray" padding="1pt" display-align="center">
                       <fo:block text-align="right">
                                <xsl:for-each select="Number"> ...
                           </xsl:for-each>
                            </fo:block>
                        </fo:table-cell>
                        <fo:table-cell border="solid 1pt gray" padding="1pt" display-align="center">
                            <fo:block text-align="left">
                                <xsl:for-each select="Description"> ...
                                </xsl:for-each>
                            </fo:block>
                        </fo:table-cell>
                        <fo:table-cell border="solid 1pt gray" padding="1pt" display-align="center"> 
                            <fo:block text-align="left" color="blue">
                               <xsl:for-each select="Answer"> ...
                               </xsl:for-each>
                            </fo:block>
                        </fo:table-cell>                                   </xsl:when>  
                    <xsl:when test="Number='1.1'">
                        <xsl:if test="//questions/Number='1.0' and //questions/Answer='No'">
                           <fo:table-cell border="solid 1pt gray" padding="1pt" display-align="center">
                               <fo:block text-align="right">
                                    <xsl:for-each select="Number"> ...
                                    </xsl:for-each>
                               </fo:block>
                           </fo:table-cell>
                           <fo:table-cell border="solid 1pt gray" padding="1pt" display-align="center">
                               <fo:block text-align="left">
                                   <xsl:for-each select="Question">  .....
                                   </xsl:for-each>
                               </fo:block>
                           </fo:table-cell>
                           <fo:table-cell border="solid 1pt gray" padding="1pt" display-align="center"> 
                              <fo:block text-align="left" color="blue">  ....
                                   <xsl:for-each select="Details">
                                   </xsl:for-each>
                              </fo:block>
                           </fo:table-cell>                                      </xsl:if>  
                       </xsl:when>  
                       <xsl:otherwise>do something</xsl:otherwise>                        </xsl:choose>
               </fo:table-row>
            </xsl:if>
        </xsl:for-each>
    </xsl:for-each>
</fo:table-body>            
4

2 回答 2

2

根据经验。如果您的代码包含大量重复项,则说明您做错了。XSLT 也不例外。

<!-- index followup questions (no zero after the dot) -->
<xsl:key 
  name="kFollowupQuestions"
  match="questions[number(substring-after(Number, '.')) != 0]" 
  use="number(substring-before(Number, '.'))"
/>

<!-- the <Survey> becomes the <fo:table-body> -->
<xsl:template match="Survey">
  <fo:table-body start-indent="0pt">
    <!-- only select main questions (with a zero after the dot) -->
    <xsl:apply-templates select="questions[number(substring-after(Number, '.')) = 0]">
      <xsl:sort select="Number" data-type="number" order="ascending" />
    </xsl:apply-templates>
  </fo:table-body>
</xsl:template>

<!-- each <questions> becomes a <fo:table-row> -->
<xsl:template match="questions">
  <xsl:variable name="qNum"   select="number(substring-before(Number, '.'))" />
  <xsl:variable name="subNum" select="number(substring-after(Number, '.'))" />
  <fo:table-row>
    <xsl:apply-templates select="Number" />
    <xsl:apply-templates select="Question" />
    <xsl:apply-templates select="Answer" />
    <xsl:apply-templates select="Details" />
  </fo:table-row>
  <!-- for main question answered with 'Yes', display followup-questions --> 
  <xsl:if test="Answer = 'Yes' and $subNum = 0">
    <xsl:apply-templates select="key('kFollowupQuestions', $qNum)">
      <xsl:sort select="Number" data-type="number" order="ascending" />
    </xsl:apply-templates>
  </xsl:if>
</xsl:template>

<!-- the <questions> children become <fo:table-cell>s -->
<xsl:template match="questions/*">
  <fo:table-cell border="solid 1pt gray" padding="1pt" display-align="center">
    <fo:block text-align="right">
      <xsl:value-of select="." /><!-- or whatever -->
    </fo:block>
  </fo:table-cell>
</xsl:template>

http://www.xmlplayground.com/K4VHM2

于 2012-08-10T20:19:32.610 回答
1

我会改变你的

<xsl:when test="Number='1.1'">
   <xsl:if test="//questions/Number='1.0' and //questions/Answer='No'">

<xsl:when test="Number='1.1'">
   <xsl:if test="../questions[Number = '1.0']/Answer = 'No'">

这是假设您没有一般的方法可以知道,对于任何问题,您是否应该在“是”答案或“否”答案上显示更多详细信息,因此<xsl:when>每个 *.0 问题都有一个单独的案例。

PS 奇怪的是,XSL<xsl:for-each select="Number">在每个内部都使用 etc.,因为在您的示例输入中<fo:block>只有一个<Number>孩子。<questions>所做的只是更改上下文节点。也许意图是使用<xsl:apply-templates select="Number" />

于 2012-08-10T19:08:36.100 回答