XSLT إلى HTML مع تجميع بسيط من بيانات XML باستخدام القوالب بدلاً من ECH

StackOverflow https://stackoverflow.com/questions/3006818

سؤال

لقد كنت أتعامل مع XSLT Off و ON منذ أن أصبحت مسؤول SharePoint ، فهو يستخدم XSLT الكثير لعرض بيانات القائمة. لقد بدأت مؤخرًا استخدامه لتحويل نتائج قاعدة البيانات التي قمت بتحويلها إلى XML باستخدام طريقة تمديد. أحاول إنتاج HTML نظيفة.

محاولتي الأولى ، عملت بشكل جيد. ومع ذلك ، اعتدت على ذلك في كل مكان ، لقد قرأت منذ ذلك الحين هذا أمر سيء القيام به. قرأت مجموعة من الأشياء حول استخدام المفاتيح ، لكنني لم أستطع فهم ذلك أو جعلها تعمل. لذلك قمت بإعادة كتابة ورقة الأنماط هذه ، أدناه إلى تلك الموجودة تحتها. ويستخدم القوالب مع عدم وجود.

<?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>

لم أقم بتضمين عينة الإدخال والإخراج ، لأن هذا يتم إنشاؤه تلقائيًا. إذا كانت هناك حاجة ، فيمكنني قضاء الكثير من الوقت ، ومحاولة إنتاج شيء ما.

سؤالي هو ، هل هذه طريقة أفضل للقيام بذلك؟ أيضًا إذا كانت الطريقة الرئيسية هي أفضل ، فهل يمكن لأي شخص أن يشرح ذلك ، أو تقديم رابط لتفسير جيد؟

هل كانت مفيدة؟

المحلول

أساسا مسألة استخدام for-each تتلخص القوالب مقابل إنشاء تحويلات أكثر قابلة لإعادة الاستخدام.

باستخدام القوالب ، يمكن أن تستفيد جميع العقد المطابقة - لا يمكن فقط تلك المستخدمة بشكل صريح في ECH - من القالب ، مما يساعد على تجنب الكود المكررة وفي الوقت نفسه يحطم الورقة إلى وحدات أصغر أسهل في إدارتها. إنه في الواقع مثل وجود إجراء ضخم أو إجراءات أصغر تدعو بعضها البعض في البرمجة الضرورية.

بينما يقترح بعض الأشخاص أن استخدام القوالب قد يكون أداءً أفضل في بعض المحركات ، إلا أنني أعتقد أن هذا لن يحدث فرقًا حقًا.

ومع ذلك ، قد ترغب في معرفة طريقة muenchian (الذي يستخدم المفاتيح) لتجميع البيانات فعليًا حيث لديك مفاتيح متكررة. استخدام 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', .))]" />

نصائح أخرى

قالب "for-ECH" هو ميزة جيدة لـ XSLT.

نصيحة استخدام "قوالب" بدلاً من "for-ECH" تتعلق في الغالب بسوء الاستخدام المحتمل لنموذج معالجة XSLT.

في مثالك واضح: "قالب" ساذج واحد والعديد من "ECH-ECH" الذي يوجه العملية.

الاستخدام الرئيسي في XSLT نفسه هو عن الأداء. تكمن فائدتها في استبدال تعبيرات XPath التي تنطوي على سفر متكرر العديد من العقد من شجرة الإدخال. طريقة Muenchian للتجميع هي استخدام خاص للمفاتيح. يمكن أن تكون التجميع البسيط على النحو الأمثل بدون استخدام المفاتيح.

من ناحية أخرى ، السكان هو حالة خاصة من التحول. أعتقد أنه من الأفضل الحفاظ على فصل XHTML الدلالي عن تحول XSLT. تحقق من www.aranedabienesraices.com.ar كمثال.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top