使用模板参数匹配标记

时间:2014-07-17 19:49:19

标签: xml xslt

是否可以使用模板参数来匹配命名空间标记?例如

<xsl:template match="abc:tag_name">
  <xsl:param name="tag_to_get" />
  <xsl:if test="abc:{$tag_to_get}"><xsl:value-of select="$tag_to_get" /> tag exists</xsl:if>
</xsl:template>

编辑: 我想转置存储在XML文档中的数据表,但并不是每个元素都有相同的子元素。所以我想迭代不同的可能子节点,在表中创建一个新行,并测试xml doc中的每个元素是否都有可能子节点给出的子节点。例如,给定以下XML:

<root>
<foo name="element_a">
  <bar />
</foo>
<foo name="element_b">
  <baz />
</foo>
</root>

我想创建

<table>
  <tr>
    <th>child</th>
    <th>element_a</th>
    <th>element_b</th>
  </tr>
  <tr>
    <!-- Which elements have bar children -->
    <td>bar</td>
    <td>X</td>
    <td></td>
  </tr>
  <tr>
    <!-- Which elements have baz children -->
    <td>baz</td>
    <td></td>
    <td>X</td>
  </tr>
</table>

所以上一个例子将成为:

   <xsl:template match="/">
      <html>
         <head>
            <style> table { border-collapse: collapse; font: "Trebuchet MS", sans-serif; } table, th, td { border: 1px solid black; }</style>
         </head>
         <body>
            <table>
               <tr>
                  <th>child</th>
                  <xsl:apply-templates select="root/foo"><xsl:with-param name="tag_to_get" select="'headers'" /></xsl:apply-templates>
               </tr>
               <tr>
                  <td>bar</td>
                  <xsl:apply-templates select="root/foo"><xsl:with-param name="tag_to_get" select="'bar'" /></xsl:apply-templates>
               </tr>
               <tr>
                  <td>baz</td>
                  <xsl:apply-templates select="root/foo"><xsl:with-param name="tag_to_get" select="'baz'" /></xsl:apply-templates>
               </tr>
            </table>
         </body>
      </html>
   </xsl:template>

   <xsl:template match="foo">
      <xsl:param name="tag_to_get" />
      <xsl:choose>
         <xsl:when test="$tag_to_get = 'headers'">
            <th><xsl:value-of select="./@name" /></th>
         </xsl:when>
         <xsl:otherwise>
            <td><!-- <xsl:if test="{$tag_to_get}">X</xsl:if>  --></td>
         </xsl:otherwise>
      </xsl:choose>
    </xsl:template>

但我不知道如何使用该参数来匹配元素。

1 个答案:

答案 0 :(得分:0)

您可以在此实例中使用 local-name()功能....

 <xsl:if test="*[local-name()=$tag_to_get]">
     <xsl:value-of select="$tag_to_get" /> tag exists
 </xsl:if>

local-name()返回没有名称空间前缀的元素的名称。

最好为您的标题设置一个完全独立的模板,并使用模式属性区分它。

尝试使用此XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/root">
      <html>
         <head/>
         <body>
            <table>
               <tr>
                  <th>child</th>
                  <xsl:apply-templates select="foo" mode="header" />
               </tr>
               <tr>
                  <td>bar</td>
                  <xsl:apply-templates select="foo">
                     <xsl:with-param name="tag_to_get" select="'bar'" />
                  </xsl:apply-templates>
               </tr>
               <tr>
                  <td>baz</td>
                  <xsl:apply-templates select="foo">
                     <xsl:with-param name="tag_to_get" select="'baz'" />
                  </xsl:apply-templates>
               </tr>
            </table>
         </body>
      </html>
   </xsl:template>

   <xsl:template match="foo" mode="header">
      <th><xsl:value-of select="@name" /></th>
   </xsl:template>

   <xsl:template match="foo">
      <xsl:param name="tag_to_get" />
      <td>
         <xsl:if test="*[local-name()=$tag_to_get]">X</xsl:if>
      </td>
   </xsl:template>
</xsl:stylesheet>

应用于XML时,输出以下内容

<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
<body><table>
<tr>
<th>child</th>
<th>element_a</th>
<th>element_b</th>
</tr>
<tr>
<td>bar</td>
<td>X</td>
<td></td>
</tr>
<tr>
<td>baz</td>
<td></td>
<td>X</td>
</tr>
</table></body>
</html>