【问题标题】:<xsl:if > How to deal with tags like "<Test/>"?<xsl:if > 如何处理像“<Test/>”这样的标签?
【发布时间】:2010-09-15 08:20:36
【问题描述】:

我对 XSL 很陌生,但遇到了一些问题。

我使用的 XML 有一些标签,例如 &lt;Example/&gt;

在我的 XSL(输出是 HTML)中,我对没有数据的标签使用了类似的东西:

<xsl:if test="count(ContractNr) > 0">  
  <td>Nr:</td>  
  <td><xsl:value-of select="ContractNr"/></td>  
</xsl:if>

没有标签的时候效果很好。

但是如何为&lt;ContractNumber/&gt; 之类的东西创建&lt;xsl:if&gt;
Ty,对不起我的英语。

更新:编辑了我的 1 篇文章,抱歉.. 我的意思是当我测试的标签在 xml 中不存在时,我的示例有效,但我如何测试标签是否为“空” " 喜欢或

ty,Treemonkey,但我不确定这是否是我正在寻找的解决方案。

我会尽量解释得更好。

在 xml 输入文件中有许多标签是“可选”或“minOccurs="0"”(根据模式)。使用 xsl 我尝试使用一个表格制作一个 html 输出,在该表格中我使用&lt;xsl:if&gt; 来确定标记是否存在于 xml 中(无标记=无列)。

我为我的 html 表格列提供静态名称(xml 中的数据不能用于命名)并将 xml 中的数据放在那里。现在,当标签为 &lt;smthng/&gt; 时,我仍然得到具有给定静态名称的列 - 这就是问题所在。我想创建一个xsl:if,这样如果有&lt;smthng/&gt;,则不会创建该列:

<table>
  <tr><xsl:if ...>
    <td>Some name:</td>
    <td><xsl:value-of select="smthng"/></td></xsl:if>
  </tr>
</table>

【问题讨论】:

  • 查看我的回答,了解 XSLT 最佳实践解决方案。不明白的请追问。另外,永远不要回答你自己的问题 - 只需编辑它。

标签: xslt


【解决方案1】:
<xsl:if test="count(ContractNr) &gt; 0">
  <td>Nr:</td>
  <td><xsl:value-of select="ContractNr"/></td>
</xsl:if>

不好 XSLT

更好用

<xsl:apply-templates select="ContractNr[1]"/>

并有一个单独的模板

<xsl:template match="ContractNr/text()">
 <td>Nr:</td>
 <td><xsl:value-of select="."/></td>
</xsl:template>

值得学习的一课:XSLT 模式匹配使其他编程语言“典型”的大量条件逻辑变得不必要。

【讨论】:

    【解决方案2】:

    &lt;ContractNumber&gt;&lt;/ContractNumber&gt;&lt;ContractNumber/&gt;不一样吗?

    查看 XML 参考:http://www.w3.org/TR/xml/#sec-starttags

    【讨论】:

      【解决方案3】:

      我编辑了我的 1 个帖子,抱歉.. 我的意思是当我测试的标签在 xml 中不存在时,我的 &lt;xsl:if&gt; 示例有效,但我如何测试标签是否为“空”,如 &lt;smthng/&gt;&lt;smthng&gt;&lt;/smthng&gt;

      ty,Treemonkey,但我不确定这是否是我正在寻找的解决方案。

      我会尽量解释得更好。

      在 xml 输入文件中有许多标签是“可选”或“minOccurs="0"”(根据模式)。 使用 xsl 我尝试使用一个表格制作 html 输出,在该表格中我使用&lt;xsl:if&gt; 来确定标签是否存在于 xml 中(无标签=无列)。
      我为我的 html 表列提供静态名称(xml 中的数据不能用于命名)并将 xml 中的数据放在那里。现在,当标签为 &lt;smthng/&gt; 时,我仍然得到具有给定静态名称的列 - 这就是问题所在。 我想创建一个 xsl:if 以便如果有 &lt;smthng/&gt; 则不创建该列:
      <table>
      <tr><xsl:if ...>
      <td>Some name:</td>
      <td><xsl:value-of select="smthng"/></td></xsl:if>
      </tr>
      </table>

      【讨论】:

        【解决方案4】:

        这是您要找的吗? 这将检查元素,然后允许您使用节点的名称,使用 local-name() 函数

        这也回答了您的第二个问题,使用节点的应用模板只会将模板应用于匹配的元素,因此与 IF 的工作方式大致相同,如果没有匹配,自然不会发生任何事情!

        <xsl:template match="/">
        <xsl:apply-templates select="ContractNumber"/>
        </xsl:template>
        
        <xsl:template match="ContractNumber">
        <div>
        <xsl:value-of select="local-name()"/>
        </div>
        </xsl:template>
        

        你可以使用下面的

        &lt;xsl:if test="ContractNumber=''"&gt; do stuff &lt;/xsl:if&gt;

        <xsl:choose>
        <xsl:when test="ContractNumber=''">
           <!--do nothing-->
        </xsl:when>
        <xsl:otherwise>
           <!--build table -->
        </xsl:otherwise>
        </xsl:choose>
        

        【讨论】:

          【解决方案5】:

          我认为这是您想要的两种解决方案。

          有了这个输入:

          <table>
             <row>
                <a>A1</a>
                <b>B1</b>
                <c>C1</c>
             </row>
             <row>
                <a>A2</a>
                <b>B2</b>
             </row>
             <row>
                <a>A3</a>
                <b/>
                <c>C3</c>
             </row>
          </table>
          

          这个样式表:

          <xsl:stylesheet version="1.0"
           xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
           xmlns:h="header"
           exclude-result-prefixes="h">
              <h:header title="First" element="a"/>
              <h:header title="Second" element="b"/>
              <h:header title="Third" element="c"/>
              <xsl:template match="table">
                  <html>
                      <table style="border:1px solid black;">
                          <tr>
                              <xsl:apply-templates select="document('')/*/h:*"
                               mode="header"/>
                          </tr>
                          <xsl:apply-templates/>
                      </table>
                  </html>
              </xsl:template>
              <xsl:template match="row">
                  <tr>
                      <xsl:apply-templates select="document('')/*/h:*">
                          <xsl:with-param name="pContext" select="."/>
                      </xsl:apply-templates>
                  </tr>
              </xsl:template>
              <xsl:template match="h:*">
                  <xsl:param name="pContext"/>
                  <td>
                      <xsl:value-of select="$pContext/*[name()=current()/@element]"/>
                  </td>
              </xsl:template>
              <xsl:template match="h:*" mode="header">
                  <th>
                      <xsl:value-of select="@title"/>
                  </th>
              </xsl:template>
          </xsl:stylesheet>
          

          输出:

          <html>
              <table style="border:1px solid black;">
                  <tr>
                      <th>First</th>
                      <th>Second</th>
                      <th>Third</th>
                  </tr>
                  <tr>
                      <td>A1</td>
                      <td>B1</td>
                      <td>C1</td>
                  </tr>
                  <tr>
                      <td>A2</td>
                      <td>B2</td>
                      <td></td>
                  </tr>
                  <tr>
                      <td>A3</td>
                      <td></td>
                      <td>C3</td>
                  </tr>
              </table>
          </html>
          

          还有这个样式表:

          <xsl:stylesheet version="1.0"
           xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
           xmlns:h="header"
           exclude-result-prefixes="h">
              <h:header title="First" element="a"/>
              <h:header title="Second" element="b"/>
              <h:header title="Third" element="c"/>
              <xsl:template match="table">
                  <html>
                      <xsl:apply-templates/>
                  </html>
              </xsl:template>
              <xsl:template match="row">
                  <table style="border:1px solid black;">
                      <xsl:apply-templates select="document('')/*/h:*">
                          <xsl:with-param name="pContext" select="."/>
                      </xsl:apply-templates>
                  </table>
              </xsl:template>
              <xsl:template match="h:*">
                  <xsl:param name="pContext"/>
                  <tr>
                      <th>
                          <xsl:value-of select="@title"/>
                      </th>
                      <td>
                          <xsl:value-of select="$pContext/*[name()=current()/@element]"/>
                      </td>
                  </tr>
              </xsl:template>
          </xsl:stylesheet>
          

          输出:

          <html>
              <table style="border:1px solid black;">
                  <tr>
                      <th>First</th>
                      <td>A1</td>
                  </tr>
                  <tr>
                      <th>Second</th>
                      <td>B1</td>
                  </tr>
                  <tr>
                      <th>Third</th>
                      <td>C1</td>
                  </tr>
              </table>
              <table style="border:1px solid black;">
                  <tr>
                      <th>First</th>
                      <td>A2</td>
                  </tr>
                  <tr>
                      <th>Second</th>
                      <td>B2</td>
                  </tr>
                  <tr>
                      <th>Third</th>
                      <td></td>
                  </tr>
              </table>
              <table style="border:1px solid black;">
                  <tr>
                      <th>First</th>
                      <td>A3</td>
                  </tr>
                  <tr>
                      <th>Second</th>
                      <td></td>
                  </tr>
                  <tr>
                      <th>Third</th>
                      <td>C3</td>
                  </tr>
              </table>
          </html>
          

          注意:我认为您使用行标题是因为元素为空或不存在的问题。请注意标题名称和列顺序(无论是否存在)的内联映射(它可能在其他输入源中)的使用。

          【讨论】:

            猜你喜欢
            • 2018-05-14
            • 1970-01-01
            • 2019-04-09
            • 1970-01-01
            • 2012-03-03
            • 2018-02-07
            • 1970-01-01
            • 2012-06-26
            • 1970-01-01
            相关资源
            最近更新 更多