2014-07-17 23 views
0

是否可以使用模板參數來匹配命名空間標記?例如使用模板參數來匹配標記

<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文檔中的每個元素是否有可能的子節點給出的子節點。因此,例如,給出下面的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> 

但我不知道怎麼用參數匹配元素。

+0

你能提供更全面的例子,包括示例XML輸入?同時指出您使用的是哪個版本的XSLT。 - 在我看來,你的問題是關於使用參數匹配元素 - 不一定與名稱空間相關。 –

+0

正確,我想使用參數匹配一個元素。我提到命名空間是因爲我不確定這是否會產生影響。 – Tybalt

+0

看起來,您事先知道輸入XML的名稱空間和要獲取的元素名稱。如果是這樣,我不清楚爲什麼你不直接使用它們;如果需要在運行時將元素名稱傳遞給樣式表,唯一的原因是將它們參數化。 –

回答

0

您可以在這種情況下使用本地名稱()函數 ....

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

本地名稱()返回元素的名稱,沒有命名空間前綴。

爲您的標題設置一個完全獨立的模板,並使用模式屬性區分它可能會更好。

試試這個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> 
+0

謝謝,我用更正後的xml更新了這個例子。我正在尋找您的解決方案不允許的多個** foo **。另外,如果** header **元素不存在,** foo/header **模板如何匹配? – Tybalt

+0

我終於明白了!我已更正了我的XSLT以提供您所需的輸出。 –