使用模板匹配测试节点是否为空或包含NULL

时间:2013-02-19 20:19:22

标签: xml xslt

编辑XML

我试图找出测试节点是否不存在或如何使用模板匹配包含单词NULL。目前我正在使用< xsl:choose>在我匹配的模板中测试。有没有更有效的方法来进行这项测试?

在XML中,如果或者节点没有eixt,或者包含单词NULL,那么我想完全跳过该节点并打印出一个声明,说明该节点为何不正确(即“TITLE不存在”或“The CONTENT为NULL“)。

在XML中我有第三个和第四个节点不应该显示任何内容,而是打印一个声明,说明为什么没有显示内容。

以下是我用来测试的XML示例:

<?xml version="1.0" encoding="utf-8"?>
<FIGURES>
  <FIGURE>
    <TITLE>Title 1</TITLE>
    <DESC>Description 1</DESC>
    <CONTENT>Content 1</CONTENT>
  </FIGURE>
  <FIGURE>
    <TITLE>Title 2</TITLE>
    <DESC>Description 2</DESC>
    <CONTENT>Content 2</CONTENT>
  </FIGURE>
  <FIGURE>
    <DESC>Description 3</DESC>
    <CONTENT>Content 3</CONTENT>
  </FIGURE>
  <FIGURE>
    <TITLE>Title 4</TITLE>
    <DESC>Description 4</DESC>
    <CONTENT>NULL</CONTENT>
  </FIGURE>     
  <FIGURE>
    <TITLE>Title 5</TITLE>
    <DESC>Description 5</DESC>
    <CONTENT>Content 5</CONTENT>
  </FIGURE>
</FIGURES>

这是我正在使用的XSLT:

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

<xsl:template match="/">
  <div class="container">
   <xsl:apply-templates />
 </div>
</xsl:template>

<xsl:template match="FIGURES">
  <ul class="list">
    <xsl:apply-templates select="FIGURE" mode="titles" />
  </ul>  
  <div class="content">
    <xsl:apply-templates select="FIGURE" mode="content" />
  </div>
</xsl:template>

<xsl:template match="FIGURE" mode="titles">
  <xsl:choose>
    <!-- Check to see if the TITLE field is empty -->
    <xsl:when test="translate(./TITLE,' ', '') = ''">The TITLE node is empty</xsl:when>                      
    <!-- Check to see if the TITLE field is NULL -->
    <xsl:when test="normalize-space(./TITLE) = 'NULL'">The TITLE node is NULL</xsl:when> 
    <!-- Check to see if the CONTENT field is empty -->
    <xsl:when test="translate(./CONTENT,' ', '') = ''">The CONTENT node is empty</xsl:when>
    <!-- Check to see if the CONTENT field is NULL -->
    <xsl:when test="normalize-space(./CONTENT) = 'NULL'">The CONTENT node is NULL</xsl:when>                                            
    <xsl:otherwise>
      <li>
        <a href="#section-{position()}">
          <h3><xsl:value-of select="TITLE" /></h3>
        </a>
        <p><xsl:value-of select="DESC" /></p>
      </li>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="FIGURE" mode="content">
  <xsl:choose>
    <!-- Check to see if the TITLE field is empty -->
    <xsl:when test="translate(./TITLE,' ', '') = ''">The TITLE node is empty</xsl:when>                      
    <!-- Check to see if the TITLE field is NULL -->
    <xsl:when test="normalize-space(./TITLE) = 'NULL'">The TITLE node is NULL</xsl:when> 
    <!-- Check to see if the CONTENT field is empty -->
    <xsl:when test="translate(./CONTENT,' ', '') = ''">The CONTENT node is empty</xsl:when>
    <!-- Check to see if the CONTENT field is NULL -->
    <xsl:when test="normalize-space(./CONTENT) = 'NULL'">The CONTENT node is NULL</xsl:when>                                            
    <xsl:otherwise>
      <div id="section-{position()}">
        <p><xsl:value-of select="CONTENT" /></p>
      </div>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>

谢谢。

2 个答案:

答案 0 :(得分:1)

这基本上会产生与XSLT相同的结果,并避免使用xsl:choose。请试一试:

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

  <xsl:template match="/">
    <div class="container">
      <xsl:apply-templates />
    </div>
  </xsl:template>

  <xsl:template match="FIGURES">
    <ul class="list">
      <xsl:apply-templates select="FIGURE" mode="titles" />
    </ul>
    <div class="content">
      <xsl:apply-templates select="FIGURE" mode="content" />
    </div>
  </xsl:template>

  <xsl:template match="FIGURE" mode="titles">
    <li>
      <a href="#section-{position()}">
        <h3>
          <xsl:value-of select="TITLE" />
        </h3>
      </a>
      <p>
        <xsl:value-of select="DESC" />
      </p>
    </li>
  </xsl:template>

  <xsl:template 
      match="FIGURE[ *[self::TITLE or self::CONTENT]
                      [not(normalize-space(.)) or normalize-space(.) = 'NULL']
                   ]"
      mode="titles">
    <xsl:apply-templates select="TITLE | CONTENT" />
  </xsl:template>

  <xsl:template match="FIGURE" mode="content">
    <div id="section-{position()}">
      <p>
        <xsl:value-of select="CONTENT" />
      </p>
    </div>
  </xsl:template>

  <xsl:template 
      match="FIGURE[ *[self::TITLE or self::CONTENT]
                      [not(normalize-space(.)) or normalize-space(.) = 'NULL']
                   ]"
      mode="content">
    <xsl:apply-templates select="TITLE | CONTENT" />
  </xsl:template>

  <xsl:template match="TITLE | CONTENT" />

  <xsl:template match="*[self::TITLE or self::CONTENT][not(normalize-space(.))]">
    <xsl:value-of select="concat('The ', local-name(), ' node is empty')"/>
  </xsl:template>

  <xsl:template match="*[self::TITLE or self::CONTENT][normalize-space(.) = 'NULL']">
    <xsl:value-of select="concat('The ', local-name(), ' node is NULL')"/>
  </xsl:template>
</xsl:stylesheet>

Please give it a try.

答案 1 :(得分:1)

这是一个产生相同结果的较短转换,并且不使用任何条件XSLT指令

<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="/*">
     <div class="container">
       <ul class="list">
         <xsl:apply-templates/>
       </ul>
       <div class="content">
           <xsl:apply-templates mode="content"/>
         </div>
     </div>
 </xsl:template>

 <xsl:template match="FIGURE">
   <li>
     <a href="#section-{position()}">
       <xsl:apply-templates select="TITLE"/>
     </a>
     <xsl:apply-templates select="DESC"/>
   </li>
 </xsl:template>

 <xsl:template match="TITLE">
   <h3><xsl:value-of select="."/></h3>
 </xsl:template>

 <xsl:template match="DESC">
   <p><xsl:value-of select="."/></p>
 </xsl:template>

 <xsl:template match="FIGURE[*[. = 'NULL' or not(normalize-space())]]">
  <xsl:apply-templates select="*[. = 'NULL' or not(normalize-space())]"/>
 </xsl:template>

 <xsl:template match="FIGURE/*[. = 'NULL']">
  The <xsl:value-of select="name()"/> node is NULL.
 </xsl:template>
 <xsl:template match="FIGURE/*[not(normalize-space())]">
  The <xsl:value-of select="name()"/> node is empty.
 </xsl:template>

 <xsl:template match="FIGURE[not(*[. = 'NULL' or not(normalize-space())])]" mode="content">
      <div id="section-{position()}">
         <p><xsl:value-of select="CONTENT"/></p>
      </div>
 </xsl:template>
 <xsl:template match="FIGURE" mode="content"/>
</xsl:stylesheet>

在提供的XML文档上应用此转换时:

<FIGURES>
    <FIGURE>
        <TITLE>Title 1</TITLE>
        <DESC>Description 1</DESC>
        <CONTENT>Content 1</CONTENT>
    </FIGURE>
    <FIGURE>
        <TITLE>Title 2</TITLE>
        <DESC>Description 2</DESC>
        <CONTENT>Content 2</CONTENT>
    </FIGURE>
    <FIGURE>
        <TITLE></TITLE>
        <DESC>Description 3</DESC>
        <CONTENT>Content 3</CONTENT>
    </FIGURE>
    <FIGURE>
        <TITLE>Title 4</TITLE>
        <DESC>Description 4</DESC>
        <CONTENT>NULL</CONTENT>
    </FIGURE>
    <FIGURE>
        <TITLE>Title 5</TITLE>
        <DESC>Description 5</DESC>
        <CONTENT>Content 5</CONTENT>
    </FIGURE>
</FIGURES>

产生与最初提供的转换相同的结果:

<div class="container">
   <ul class="list">
      <li>
         <a href="#section-1">
            <h3>Title 1</h3>
         </a>
         <p>Description 1</p>
      </li>
      <li>
         <a href="#section-2">
            <h3>Title 2</h3>
         </a>
         <p>Description 2</p>
      </li>
  The TITLE node is empty.

  The CONTENT node is NULL.
 <li>
         <a href="#section-5">
            <h3>Title 5</h3>
         </a>
         <p>Description 5</p>
      </li>
   </ul>
   <div class="content">
      <div id="section-1">
         <p>Content 1</p>
      </div>
      <div id="section-2">
         <p>Content 2</p>
      </div>
      <div id="section-5">
         <p>Content 5</p>
      </div>
   </div>
</div>