Добавить JavaScript в XSL-файл, или какую функцию xsl я мог бы использовать - PullRequest
0 голосов
/ 24 апреля 2019

В XSL-файле, который анализирует XML и просматривает его как таблицу, я должен сделать заголовок таблицы одним полем, активируемым щелчком мыши, и изменить вид таблицы. Как это можно сделать? Я попытался сделать заголовок таблицы содержащей ссылку с функцией onclick = "f1 ()", чтобы перейти к функции JavaScript, которая изменяет innerHTML элемента div. Но это не сработало. Можно ли добавить 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 голосов
/ 24 апреля 2019

Вы можете делегировать сортировку в 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 , используемый Javascript, такой как Array.from, должен работать во всех современных браузерах, только для IE вам понадобится использовать полифилл, чтобы иметь возможность использовать этот метод, как это сделано в https://xsltfiddle.liberty -development.net / 6r5Gh3r / 4 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...