将JavaScript添加到XSL文件中,或者我可以使用什么xsl函数

时间:2019-04-24 06:47:49

标签: xml xslt

在解析XML并将其作为表查看的XSL文件中,我应该使一个字段的表头可单击,并改变表的种类。那怎么办?我试图使表头包含一个带有onclick =“ f1()”函数的链接,以转到更改div的innerHTML的JavaScript函数。但这没有用。是否可以将JavaScript添加到XSL文件中?还有什么其他方法可以实现呢?

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html> 
<body>
<script>
function p2(){
        var pp1 = document.getElementById("p1");
        pp1.innerHTML = "<xsl:for-each select=\"catalog/cd\">\n" +
        "<xsl:sort select=\"artist\"/>\n" +
        "<tr>\n" +
        "<td><xsl:value-of select=\"title\"/></td>\n" +
        "<td><xsl:value-of select=\"artist\" sort=\"ascending\" />\n" +
        "</tr>\n" +
        "</xsl:for-each>";
}
</script>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th style="text-align:left">Title</th>
      <th style="text-align:left">
       <a href="#" onclick="p2()">Artist </a></th>
    </tr>
    <div id="p1">
    <xsl:for-each select="catalog/cd">
    <tr>
      <td><xsl:value-of select="title"/></td>
      <td><xsl:value-of select="artist" />
    </tr>
    </xsl:for-each>
   </div>
  </table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

到目前为止,我正在使用https://www.w3schools.com/xml/tryxslt.asp?xmlfile=cdcatalog&xsltfile=cdcatalog

进行解析

1 个答案:

答案 0 :(得分:0)

您可以将排序委托给Javascript,将要排序的行填充到Javascript数组中,以便可以使用其sort方法(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort):

        function sort(headerCell) {
           var table = headerCell.parentNode.parentNode.parentNode;
           var tbody = table.tBodies[0];
           var rows = Array.from(tbody.rows);
           var cellIndex = headerCell.cellIndex;

           if ('oldIndex' in table.dataset) {
             table.tHead.rows[0].cells[table.dataset.oldIndex].classList.remove('sorted-asc', 'sorted-desc');
           }

           table.dataset.oldIndex = cellIndex;

           var prefix = headerCell.dataset.sortOrder === 'ascending' ? 1 : -1;

           if (headerCell.dataset.sortOrder === 'ascending') {
             headerCell.classList.remove('sorted-desc');
             headerCell.classList.add('sorted-asc');
           }
           else {
             headerCell.classList.remove('sorted-asc');
             headerCell.classList.add('sorted-desc');               
           }

           headerCell.dataset.sortOrder = headerCell.dataset.sortOrder === 'ascending' ? 'descending' : 'ascending';

           var numeric = headerCell.dataset.type === 'number';

           rows.sort(
             function(a, b) { 
               return prefix * a.cells[cellIndex].textContent.localeCompare(b.cells[cellIndex].textContent, undefined, { 'numeric' : numeric });
             }
           );
           rows.forEach(function(row) { tbody.appendChild(row); });
        }

然后,您可以仅在要支持排序的任何表标题单元格上使用<th onclick="sort(this);">...</th>,例如,如果要对所有标题单元格执行此操作,则可以为其编写模板:

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exsl="http://exslt.org/common"
    xmlns:msxml="urn:schemas-microsoft-com:xslt"
    exclude-result-prefixes="exsl msxml"
    version="1.0">

  <xsl:output method="html" indent="yes" version="5" doctype-system="about:legacy-doctype"/>

  <xsl:template match="/">
    <html>
      <head>
        <title>.NET XSLT Fiddle Example</title>
        <style>
            .sorted-asc::after { content : '↑' }
            .sorted-desc::after { content : '↓' }
        </style>
        <script>
            function sort(headerCell) {
               var table = headerCell.parentNode.parentNode.parentNode;
               var tbody = table.tBodies[0];
               var rows = Array.from(tbody.rows);
               var cellIndex = headerCell.cellIndex;

               if ('oldIndex' in table.dataset) {
                 table.tHead.rows[0].cells[table.dataset.oldIndex].classList.remove('sorted-asc', 'sorted-desc');
               }

               table.dataset.oldIndex = cellIndex;

               var prefix = headerCell.dataset.sortOrder === 'ascending' ? 1 : -1;

               if (headerCell.dataset.sortOrder === 'ascending') {
                 headerCell.classList.remove('sorted-desc');
                 headerCell.classList.add('sorted-asc');
               }
               else {
                 headerCell.classList.remove('sorted-asc');
                 headerCell.classList.add('sorted-desc');               
               }

               headerCell.dataset.sortOrder = headerCell.dataset.sortOrder === 'ascending' ? 'descending' : 'ascending';

               var numeric = headerCell.dataset.type === 'number';

               rows.sort(
                 function(a, b) { 
                   return prefix * a.cells[cellIndex].textContent.localeCompare(b.cells[cellIndex].textContent, undefined, { 'numeric' : numeric });
                 }
               );
               rows.forEach(function(row) { tbody.appendChild(row); });
            }
        </script>
      </head>
      <body>
          <h1>Example</h1>
          <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="catalog">
      <table>
          <thead>
              <tr>
                  <xsl:apply-templates select="*[1]/*" mode="header"/>
              </tr>
          </thead>
          <tbody>
              <xsl:apply-templates/>
          </tbody>
      </table>
  </xsl:template>

  <xsl:template match="*" mode="header">
      <th onclick="sort(this);" data-sort-order="ascending">
          <xsl:attribute name="data-type">
              <xsl:choose>
                  <xsl:when test="number() != number()">text</xsl:when>
                  <xsl:otherwise>number</xsl:otherwise>
              </xsl:choose>
          </xsl:attribute>
          <xsl:value-of select="local-name()"/>
      </th>
  </xsl:template>

  <xsl:template match="catalog/*">
      <tr>
          <xsl:apply-templates/>
      </tr>
  </xsl:template>

  <xsl:template match="catalog/*/*">
      <td>
          <xsl:apply-templates/>
      </td>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/6r5Gh3r/3的在线示例中,像Array.from这样的使用过的Javascript应该可以在所有现代浏览器中使用,仅对于IE,您需要使用polyfill才能使用该方法,就像在{{ 3}}。

相关问题