XSLT:在另一个模板中重用模板

时间:2014-12-05 17:45:09

标签: xml templates xslt

我有一个XSLT文件,显示CD的标题和艺术家名称。我有3个模板,第一个模板显示标题,第二个模板显示艺术家名称,第三个模板包含隐藏表。使用复选框显示隐藏表。我想重用标题和艺术家模板,以便在可见时将它们显示为第三个模板中的表数据。

问题是第三个模板没有在浏览器上显示,因为我不知道要为匹配属性分配什么。任何帮助都非常感谢。感谢。

预期成果: http://oi61.tinypic.com/6ibkur.jpg![1] 的index.html

<html>
<head>
<script>
function loadXMLDoc(filename)
{
if (window.ActiveXObject)
  {
  xhttp = new ActiveXObject("Msxml2.XMLHTTP");
  }
else 
  {
  xhttp = new XMLHttpRequest();
  }
xhttp.open("GET", filename, false);
try {xhttp.responseType = "msxml-document"} catch(err) {} // Helping IE11
xhttp.send("");
return xhttp.responseXML;
}

function displayResult()
{
xml = loadXMLDoc("cdcatalog.xml");
xsl = loadXMLDoc("cdcatalog_apply.xsl");
// code for IE
if (window.ActiveXObject || xhttp.responseType == "msxml-document")
  {
  ex = xml.transformNode(xsl);
  document.getElementById("example").innerHTML = ex;
  }
// code for Chrome, Firefox, Opera, etc.
else if (document.implementation && document.implementation.createDocument)
  {
  xsltProcessor = new XSLTProcessor();
  xsltProcessor.importStylesheet(xsl);
  resultDocument = xsltProcessor.transformToFragment(xml, document);
  document.getElementById("example").appendChild(resultDocument);
  }
}
</script>
</head>
<body onload="displayResult()">
<div id="example" />
</body>
</html>

cdcatalog.xml

<?xml version="1.0" encoding="UTF-8"?>

<catalog>
    <cd>
        <title>Empire Burlesque</title>
        <artist>Bob Dylan</artist>
    </cd>
    <cd>
        <title>Hide your heart</title>
        <artist>Bonnie Tyler</artist>
    </cd>
    <cd>
        <title>Greatest Hits</title>
        <artist>Dolly Parton</artist>
    </cd>
</catalog>

cdcatalog_apply.xsl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/">
    <html>
    <head>
    <style type="text/css"> 

    .pdesc{
    display:none;
    }

    input[type=checkbox]:checked + .pdesc {
      display: block;
    }

    </style>
    </head>
    <body>

      <h1>CD Collection</h1>
      <xsl:apply-templates select="catalog/cd">
      </xsl:apply-templates>

    </body>
    </html>
    </xsl:template>


    <xsl:template match="cd">
    <TR >
    <xsl:apply-templates select="title"/>
    <xsl:apply-templates select="artist"/>
    </TR>
    </xsl:template>


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


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

    <xsl:template match="X"><!-- I don't know what to put in the match -->
    <label >Show More</label>
    <input type="checkbox" ></input>

    <div class="pdesc">

    <h2>CD Details</h2>

    <table border="1" >
    <tr bgcolor="#9acd32">
      <th>Title</th>
      <th>Artist</th>
    <tr>
      <td> <xsl:call-template name="title"/></td>
      <td> <xsl:call-template name="artist"/></td>
    </tr>

    </tr>
    </table>

    </div>
    </xsl:template>


</xsl:stylesheet>

1 个答案:

答案 0 :(得分:0)

在没有某种条件的情况下,您不能拥有两个完全匹配相同元素的模板,因此您无法匹配&#34; cd&#34;在你的第三个模板中。

你可以这么做,就是给你的第三个模板一个&#34;模式&#34;属性

<xsl:template match="cd" mode="hidden">

但是,您需要在指定模式的地方使用第二个xsl:apply-templates

 <xsl:apply-templates select="catalog/cd" />
 <xsl:apply-templates select="catalog/cd" mode="hidden" />

或许你可以在匹配&#34; cd&#34;的模板中调用它。目前:

<xsl:template match="cd">
    <TR>
        <xsl:apply-templates select="title"/>
        <xsl:apply-templates select="artist"/>
        <xsl:apply-templates select="." mode="hidden" />
    </TR>
</xsl:template>

注意,在这个&#34;隐藏&#34;模板,你真的不需要像现在这样做xsl:call-templates。您可以像第一个模板一样再次<xsl:apply-templates select="title"/>

或者,您可以删除第一个模板,并使用xsl:for-each代替第一个<xsl:apply-templates select="cd">。这将取消对&#34;模式&#34;的需求。属性。

<xsl:for-each select="catalog/cd">
    <TR>
         <xsl:apply-templates select="title"/>
         <xsl:apply-templates select="artist"/>
         <xsl:apply-templates select="."  />
      </TR>
 </xsl:for-each>

当然,你真的需要两个模板吗?你不能把它们组合成一个吗?

<xsl:template match="cd">
    <p>
        <xsl:apply-templates select="title"/>
        <xsl:apply-templates select="artist"/>
    </p>
    <label>Show More</label>
    <input type="checkbox" />
    <div class="pdesc">
        <h2>CD Details</h2>

        <table border="1" >
        <tr bgcolor="#9acd32">
          <th>Title</th>
          <th>Artist</th>
        <tr>
          <td><xsl:apply-templates select="title"/></td>
          <td><xsl:apply-templates select="artist"/></td>
        </tr>
        </tr>
        </table>
    </div>
</xsl:template>