使用XSLT进行条件显示..?

时间:2011-10-14 07:50:16

标签: html xml xslt

下面是我的XML代码 -

<topic no=1>
<desc>......</desc>
<references>
    <book>XSLT Essentials</book>
    <chapter>11</chapter>
    <book>XSLT Cookbook</book>
    <chapter>10</chapter>
</references>
</topic>    

<topic no=2>
<desc>......</desc>
<references>
    <book>Javascript in 10 mins</book>
    <chapter>11</chapter>
</references>
</topic>

<topic no=3>
<desc>......</desc>
<references>
    <book></book>
    <chapter></chapter>
</references>
</topic>

首先我要解释一下情况。

仅针对引用标记的HTML输出,我正在寻找就像 -

主题no = 1

<table><tr>
  <td>Book</td><td>Chapter</td></tr>
<tr>
  <td>XSLT Essentials</td><td>11</td></tr>
<tr>
  <td>XSLT Cookbook</td><td>10</td></tr>
</table>

...

主题no = 2

<table><tr>
  <td>Book</td><td>Chapter</td></tr>
<tr>
  <td>Javascript in 10 mins</td><td>11</td></tr>
</table>

...

主题no = 3 没有表格,因为没有使用过引用。

这是一个示例,因此XML文件在第一种情况下仅包含2个引用,但在某些情况下这些引用甚至可能会转到12,在某些情况下甚至会转到0(零)。

度过美好的一天 - 约翰:)

3 个答案:

答案 0 :(得分:0)

这样做:

<xsl:template match="content">

    <xsl:apply-templates select="references" />
</xsl:template>
<xsl:template match="references">
          <xsl:if test="book != '']">
           <table>
           <tr><td>Book</td><td>Chapter</td></tr>
           <xsl:apply-templates select="book" />
         </table>
          </xsl:if>
</xsl:template>
<xsl:template match="book">
    <tr><td><xsl:value-of select="." /></td><td><xsl:value-of select="following-sibling::chapter[1]" /></td></tr>
</xsl:template>

测试并且有效;)

答案 1 :(得分:0)

为此,看起来您首先需要将参数传递给XSLT以指示您想要的主题。如何做到这一点取决于您使用的处理器,但在您的XSLT中,您将需要以下行:

<xsl:param name="topic" select="'1'"/>

(1是此处的默认参数)

然后,要获取参数的所有相关主题,只需执行以下操作:

<xsl:apply-templates select="//topic[@no=$topic][references/book != '']"/>

这也将忽略没有引用的主题。

因此,给出以下XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:param name="topic" select="'1'"/>

   <xsl:template match="/">
      <xsl:if test="//topic[@no=$topic][references/book != '']">
         <table>
            <tr>
               <td>Book</td>
               <td>Chapter</td>
            </tr>
            <xsl:apply-templates select="//topic[@no=$topic][references/book != '']"/>
         </table>
      </xsl:if>
   </xsl:template>

   <xsl:template match="topic">
      <xsl:apply-templates select="references"/>
   </xsl:template>

   <xsl:template match="references">
      <xsl:apply-templates select="book"/>
   </xsl:template>

   <xsl:template match="book">
      <tr>
         <td>
            <xsl:value-of select="."/>
         </td>
         <td>
            <xsl:value-of select="following-sibling::chapter[1]"/>
         </td>
      </tr>
   </xsl:template>
</xsl:stylesheet>

应用于以下输入XML

<topics>
   <topic no="1">
      <desc>......</desc>
      <references>
         <book>XSLT Essentials</book>
         <chapter>11</chapter>
         <book>XSLT Cookbook</book>
         <chapter>10</chapter>
      </references>
   </topic>
   <topic no="2">
      <desc>......</desc>
      <references>
         <book>Javascript in 10 mins</book>
         <chapter>11</chapter>
      </references>
   </topic>
   <topic no="3">
      <desc>......</desc>
      <references>
         <book/>
         <chapter/>
      </references>
   </topic>
</topics>

以下是输出

<table>
   <tr>
      <td>Book</td>
      <td>Chapter</td>
   </tr>
   <tr>
      <td>XSLT Essentials</td>
      <td>11</td>
   </tr>
   <tr>
      <td>XSLT Cookbook</td>
      <td>10</td>
   </tr>
</table>

当参数更改为2时,输出以下内容:

<table>
   <tr>
      <td>Book</td>
      <td>Chapter</td>
   </tr>
   <tr>
      <td>Javascript in 10 mins</td>
      <td>11</td>
   </tr>
</table>

当参数更改为3时,不输出任何内容。

答案 2 :(得分:0)

这可能是最简单,最短的解决方案之一。请注意,根本没有使用明确的条件指令

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="topic/*|text()"/>

 <xsl:template match="/*[topic]">
       <xsl:apply-templates/>
 </xsl:template>

 <xsl:template match="topic/references[book/text()]">
    <table>
     <tr><td>Book</td><td>Chapter</td></tr>
   <xsl:apply-templates select="book"/>
    </table>
 </xsl:template>

 <xsl:template match="book">
  <tr>
   <td><xsl:value-of select="."/></td>
   <td><xsl:value-of select=
       "following-sibling::chapter[1]"/>
   </td>
  </tr>
 </xsl:template>
</xsl:stylesheet>

应用于提供的输入文本(已更正为格式良好的XML文档):

<t>
    <topic no="1">
        <desc>......</desc>
        <references>
            <book>XSLT Essentials</book>
            <chapter>11</chapter>
            <book>XSLT Cookbook</book>
            <chapter>10</chapter>
        </references>
    </topic>
    <topic no="2">
        <desc>......</desc>
        <references>
            <book>Javascript in 10 mins</book>
            <chapter>11</chapter>
        </references>
    </topic>
    <topic no="3">
        <desc>......</desc>
        <references>
            <book></book>
            <chapter></chapter>
        </references>
    </topic>
</t>

产生了想要的正确结果

<table>
   <tr>
      <td>Book</td>
      <td>Chapter</td>
   </tr>
   <tr>
      <td>XSLT Essentials</td>
      <td>11</td>
   </tr>
   <tr>
      <td>XSLT Cookbook</td>
      <td>10</td>
   </tr>
</table>
<table>
   <tr>
      <td>Book</td>
      <td>Chapter</td>
   </tr>
   <tr>
      <td>Javascript in 10 mins</td>
      <td>11</td>
   </tr>
</table>

解释:正确使用模板模式匹配。

Dimitre规则:每当您有明确的条件指令(<xsl:if><xsl:choose><xsl:when>等)时,这可能意味着您你应该使用模板模式匹配。

要了解更多完全避免条件指示的原因: 阅读这个必要的Pluralsight课程:

Tactical Design Patterns in .NET: Control Flow

Zoran Horvat