2010-06-09 3 views
3

Я уже возился с xslt, так как я стал администратором sharepoint, он использует xslt alot для отображения данных списка. Я недавно начал использовать его для преобразования результатов базы данных, которые я преобразовал в xml, используя метод расширения. Я пытаюсь создать чистый html.XSLT В HTML с простой группировкой XML-данных с использованием шаблонов вместо for-each

Моя первая попытка, работала нормально. Однако я использовал для каждого по всему месту, с тех пор я читал, что это плохо. Я прочитал кучу вещей об использовании ключей, но я не мог понять этого или заставить его работать. Поэтому я переписал эту таблицу стилей, ниже той, которая находится ниже нее. Он использует шаблоны без каких-либо.

<?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> 
    <head> 
    <link rel="Stylesheet" type="text/css" href="../styles/BoxReportStyle.css" /> 
    </head> 
    <body> 


    <span class="BoxReport"> 
     <h2>Checked Out Boxes by Department with Transaction History</h2> 

     Count=<xsl:value-of select="count(/CheckedOutBoxes/row) "/> 

    <!-- Get the divisions, since we are groing to group by division--> 
    <xsl:variable name="DivisionList" select="/CheckedOutBoxes/row[ not(Division = preceding-sibling::row/Division) ]/Division" /> 

    <xsl:for-each select="$DivisionList"> 

     <xsl:variable name="DivisionName" select="." /> 

     <h3> 
     <xsl:value-of disable-output-escaping="yes" select="$DivisionName "/> 
     </h3> 

     <!-- Get the list of departments, so we can group by department --> 
     <xsl:variable name="DepartmentList" select="/CheckedOutBoxes/row[ Division = $DivisionName and not(Department = preceding-sibling::row/Department) ]/Department" /> 

     <xsl:for-each select="$DepartmentList"> 
     <xsl:variable name="DepartmentName" select="." /> 

     <h4> 
      <xsl:value-of disable-output-escaping="yes" select="$DepartmentName"/> 
     </h4> 

     <xsl:variable name="Rows" select="/CheckedOutBoxes/row[ Division = $DivisionName and Department = $DepartmentName ]" /> 

     <!-- Start displaying the checked out box information for this division and department --> 
     <table> 
      <th>Box Number</th> 
      <th>Status Name</th> 
      <th>Entry Date</th> 
      <th>Description</th> 

      <xsl:for-each select="$Rows"> 

      <tr> 
       <td> 
       <xsl:value-of select="BoxNumber"/> 
       </td> 
       <td> 
       <xsl:value-of select="StatusName"/> 
       </td> 
       <td> 
       <xsl:value-of select="EntryDate"/> 
       </td> 
       <td width="200px"> 
       <xsl:value-of disable-output-escaping="yes" select="Description"/> 
       </td> 

      </tr> 

      <!-- Now display the transaction history if there is any--> 
      <xsl:if test=" count(Transaction) > 0 "> 
       <tr> 
       <td></td> <!-- One blank row to shift things over--> 
       <td colspan="3"> 
        <!-- Display transaction table--> 
        <table class="SubTable"> 
        <th>Transaction Date</th> 
        <th>Requestor</th> 
        <th>Comments</th> 

        <xsl:for-each select="Transaction" > 
         <tr> 
         <td> 
          <xsl:value-of select="TransactionDate"/> 
         </td> 
         <td> 
          <xsl:value-of select="Requestor"/> 
         </td> 
         <td width="200px"> 
          <xsl:value-of disable-output-escaping="yes" select="Comments"/> 
         </td> 
         </tr> 
        </xsl:for-each> 
        </table> 
       </td> 
       </tr> 
      </xsl:if> 
      </xsl:for-each> 
     </table> 

     </xsl:for-each> 

    </xsl:for-each> 
    </span> 


    </body> 

</html> 


    </xsl:template> 



</xsl:stylesheet> 

Теперь я переписал, что к этому:

<?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> 
    <head> 
    <link rel="Stylesheet" type="text/css" href="../styles/BoxReportStyle.css" /> 
    </head> 
    <body> 
    <span class="BoxReport"> 

     <h2>Checked Out Boxes by Department with Transaction History</h2> 

     Count=<xsl:value-of select="count(/CheckedOutBoxes/row) "/> 

     <xsl:apply-templates mode="Division" select="/CheckedOutBoxes/row[ not(Division = preceding-sibling::row/Division) ]"></xsl:apply-templates> 


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

<xsl:template mode="Division" match="row"> 
<h3> 
    <xsl:value-of select="Division" disable-output-escaping="yes"/> 
</h3> 

<xsl:variable name="DivisionName" select="Division" /> 

<xsl:apply-templates mode="Department" select="/CheckedOutBoxes/row[ Division = $DivisionName and not(Department = preceding-sibling::row/Department) ]"></xsl:apply-templates> 

</xsl:template> 

<xsl:template mode="Department" match="row"> 
<h4> 
    <xsl:value-of select="Department" disable-output-escaping="yes"/> 
</h4> 

<xsl:variable name="DivisionName" select="Division" /> 
<xsl:variable name="DepartmentName" select="Department" /> 

<table> 
    <th>Box Number</th> 
    <th>Status Name</th> 
    <th>Entry Date</th> 
    <th>Description</th> 

    <xsl:apply-templates mode="row" select="/CheckedOutBoxes/row[ Division = $DivisionName and Department = $DepartmentName ]" ></xsl:apply-templates> 

    </table> 



</xsl:template> 

<xsl:template mode="row" match="row"> 

<tr> 
    <td> 
    <xsl:value-of select="BoxNumber"/> 
    </td> 
    <td> 
    <xsl:value-of select="StatusName"/> 
    </td> 
    <td> 
    <xsl:value-of select="EntryDate"/> 
    </td> 
    <td width="200px"> 
    <xsl:value-of disable-output-escaping="yes" select="Description"/> 
    </td> 

</tr> 

<!-- Display Transaction stuff as another row if we have any --> 
<xsl:if test=" count(Transaction) > 0 "> 
    <tr> 
    <td></td><!-- Shift the transaction over--> 
    <td colspan="3"> 
     <!-- Start Transaction Table --> 
     <table class="SubTable"> 
     <th>Transaction Date</th> 
     <th>Requestor</th> 
     <th>Comments</th> 

     <xsl:apply-templates select="Transaction"> 
      <xsl:sort order="descending" select="TransactionDate"/> 
     </xsl:apply-templates> 
     </table> 
    </td> 
    </tr> 
</xsl:if> 

</xsl:template> 


<xsl:template match="Transaction"> 
<tr> 
    <td> 
    <xsl:value-of select="TransactionDate"/> 
    </td> 
    <td> 
    <xsl:value-of select="Requestor"/> 
    </td> 
    <td width="200px"> 
    <xsl:value-of disable-output-escaping="yes" select="Comments"/> 
    </td> 
</tr> 
    </xsl:template> 

</xsl:stylesheet> 

Я не включал пример ввода и вывода, так как это все автогенерируемая. Если это необходимо, я могу потратить много времени и попытаться что-то сделать.

Мой вопрос в том, что это лучший способ сделать это? Также, если ключевой путь лучше, может кто-нибудь объяснить это, или предоставить ссылку на хорошее объяснение?

ответ

1

В основном вопрос использования for-each против шаблонов сводится к созданию многоразовых, более общих преобразований.

С помощью шаблонов все подходящие узлы - не только те, которые явно используются в каждом для каждого - могут извлечь выгоду из шаблона, что помогает избежать дублирования кода и в то же время разбивает лист на более мелкие единицы, которые легче управлять , На самом деле это почти то же самое, что и огромная процедура или более мелкие процедуры, вызывающие друг друга в императивном программировании.

Хотя некоторые люди предполагают, что использование некоторых шаблонов может работать лучше в некоторых машинах, я считаю, что это не будет иметь особого значения.

Таким образом, вы можете узнать о muenchian method (который использует ключи) для фактической группировки данных, где у вас есть повторяющиеся ключи. Использование оси preceding-sibling очень медленно на некоторых двигателях, поэтому лучше избегать ее, когда это не совсем необходимо.

Нечто подобное необходимо сделать трюк для подразделений (не проверено):

<xsl:key name="divisions" match="/CheckedOutBoxes/row/Division" use="." /> 

...

<xsl:apply-templates mode="Division" select="/CheckedOutBoxes/Division[generate-id(.)=generate-id(key('divisions', .))]" /> 
+0

Имеет ли ключ получить все не дублированные подразделения? Возможно, я мог бы лучше понять это, если это то, что он делает. Тогда я мог бы просто сделать еще один ключ для отдела, который был в основном таким же, как подразделения. Тогда инструкция select шаблона apply будет проверять, что я делаю отделы для текущего деления, а не все из них. – 249076

+1

Функция 'key()' в этом случае в основном возвращает набор узлов со всеми соответствующими 'Divisions'. «Магия» здесь - это функция «generate-id()», которая возвращает уникальный идентификационный идентификатор для первого узла в наборе узлов, переданных в него. Поэтому каждый идентификатор узла «Division» сравнивается с идентификатором первого узла с одним и тем же контентом (поэтому мы используем функцию 'key()'), которая поэтому будет сопоставляться только один раз для отдельного содержимого. – Lucero

+0

Ну, я думаю, что после выполнения немного работы с шаблонами, чтобы сделать его там, где шаблоны отдела и отдела совпали с подразделением и отделом вместо строки, и реализовав ключевой материал, который я получил, чтобы работать вместо предыдущего брата. Я сейчас все понимаю немного, но, надеюсь, я начну лучше понимать его после учебы. – 249076

1

"За-каждый" шаблон является хорошей особенностью XSLT.

Советуем использовать «шаблоны» вместо «для каждого» в основном о возможном неправильном использовании модели обработки XSLT.

В вашем примере ясно: один наивный «шаблон» и множество «для каждого», которые определяют процесс.

Использование ключа в XSLT само по себе является производительностью. Его полезность заключается в замене выражений XPath, которые включают повторное перемещение многих узлов дерева ввода. Muenchian метод группировки - специальное применение для ключей. Простая группировка может быть оптимальной без использования ключей.

С другой стороны, население является частным случаем трансформации. Я считаю, что лучше поддерживать разделение семантики XHTML с преобразованием XSLT.В качестве примера рассмотрим www.aranedabienesraices.com.ar.

+0

Думаю, я вижу, где находятся шаблоны, разрывайте ситуацию. Это почти как вызовы функций. Таким образом, с совпадением «/» я могу видеть общий макет, затем я могу следить за применением шаблонов для перехода через преобразование. Я, вероятно, сохраню обе таблицы стилей. – 249076

Смежные вопросы