XLST: создать несколько таблиц - PullRequest
0 голосов
/ 09 марта 2020

Я пытаюсь использовать оператор for-each для создания таблицы для каждого элемента "bill". Документ XML выглядит следующим образом:

<group>
  <name>Casa Miles</name>
    <student>
      <id>sergio</id>
      <name>sergio</name>
      <surname>zavota</surname>
      <bill>
        <product>
          <name>sapone piatti</name>
          <amount>1</amount>
          <prize>3.3</prize>
          <participant>
            <id>stefano</id>
          </participant>
        </product>
        <product>
          <name>bresaola</name>
          <amount>1</amount>
          <prize>5.5</prize>
          <participant>
            <id>sergio</id>
          </participant>
        </product>
        <date>2020-02-03</date>
      </bill>
    </student>

    <student>
      <id>stefano</id>
      <name>stefano</name>
      <surname>silvestri</surname>
        <bill>
          <product>
            <name>liquore</name>
            <amount>2</amount>
            <prize>5.00</prize>
            <participant>
              <id>stefano</id>
            </participant>
          </product>
          <product>
            <name>coniglio</name>
            <amount>1</amount>
            <prize>4.5</prize>
            <participant>
              <id>stefano</id>
            </participant>
          </product>
          <date>2020-03-03</date>
        </bill>
      </student>
    </group>

Я пытался использовать мюнхенскую группировку, но вместо того, чтобы получить две таблицы (по одной на каждую дату / счет), я получаю только одну таблицу с датой первый счет (сверху вниз документа XML) и две строки, по одной для каждого первого продукта каждого счета, как показано на этом изображении.

https://ibb.co/TbK23JG

XSLT do c выглядит следующим образом:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:key name="tableByBillDate" match="bill" use="date" />

<xsl:template match="/">
  <html>
    <head>
      <title>HTML Document</title>
    </head>

    <style>
        table {
          font-family: arial, sans-serif;
          border-collapse: collapse;
          width: 100%;
        }

        td, th {
          border: 1px solid #dddddd;
          text-align: left;
          padding: 8px;
        }

        tr:nth-child(even) {
            background-color: #dddddd;
        }   

        caption {
          display: table-caption;
          text-align: center;
        }
    </style>

    <body>

      <h3>Welcome<xsl:value-of select="group/student/name"/></h3>
      <h3>Group: <xsl:value-of select="group/name"/> </h3>
      <h3>Bills</h3>

      <xsl:for-each select="group/student/bill[generate-id() = generate                               
      id(key('tableByBillDate',date)[1])]">

        <table>
          <caption style="font-weight: bold;">Date: <xsl:value-of select="date"/></caption>

          <tr>
            <th>Name</th> 
            <th>Amount</th>
            <th>Cost</th>
            <th>Total</th>
           <th>Participants</th>        
          </tr>

          <xsl:for-each select="key('tableByBillDate',date)">
          <xsl:sort select="date" order="descending"/> 
            <tr>
              <td><xsl:value-of select="product/name"/></td>
              <td><xsl:value-of select="product/amount"/></td>
              <td><xsl:value-of select="product/prize"/></td>
              <td>Calculated with Javascript</td>
              <td><xsl:value-of select="product/participant"/></td>   
           </tr>
         </xsl:for-each>
        </table>
      </xsl:for-each>
    </body>
  </html>
</xsl:template>
</xsl:stylesheet>

Ответы [ 2 ]

2 голосов
/ 09 марта 2020

Пожалуйста, найдите правильное следующее:

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

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:strip-space elements="yes"/>
    <xsl:key name="tableByBillDate" match="bill" use="date" />

    <xsl:template match="/">
        <html>
            <head>
                <title>HTML Document</title>
            </head>

            <style>
                table {
                font-family: arial, sans-serif;
                border-collapse: collapse;
                width: 100%;
                }

                td, th {
                border: 1px solid #dddddd;
                text-align: left;
                padding: 8px;
                }

                tr:nth-child(even) {
                background-color: #dddddd;
                }   

                caption {
                display: table-caption;
                text-align: center;
                }
            </style>

            <body>

                <h3 align="center">Welcome: <xsl:value-of select="group/student/name"/></h3>
                <h3 align="center">Group: <xsl:value-of select="group/name"/> </h3>
                <h3 align="center">Bills</h3>

                <xsl:for-each select="group/student/bill[generate-id()= generate-id(key('tableByBillDate',date)[1])]">

                    <table>
                        <caption style="font-weight: bold;">Date: <xsl:value-of select="date"/></caption>

                        <tr>
                            <th>Name</th> 
                            <th>Amount</th>
                            <th>Cost</th>
                            <th>Total</th>
                            <th>Participants</th>        
                        </tr>

                        <xsl:for-each select="key('tableByBillDate',date)">
                            <xsl:sort select="date" order="descending"/> 
                            <tr>
                                <td><xsl:value-of select="product/name"/></td>
                                <td><xsl:value-of select="product/amount"/></td>
                                <td><xsl:value-of select="product/prize"/></td>
                                <td>Calculated with Javascript</td>
                                <td><xsl:value-of select="product/participant"/></td>   
                            </tr>
                        </xsl:for-each>
                    </table>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/gVhDDyA/5

2 голосов
/ 09 марта 2020

Я также думаю, что ваш использованный ключ должен дать вам две таблицы с примерами данных, которые вы показываете, так как у вас есть две разные даты; если вы хотите вывести все данные о продукте в каждой таблице, обработайте все product s в «группе»:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

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

  <xsl:key name="tableByBillDate" match="bill" use="date" />

  <xsl:template match="group">
      <xsl:apply-templates select="student/bill[generate-id() = generate-id(key('tableByBillDate', date)[1])]">
          <xsl:sort select="date"/>
      </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="bill">
   <table>
     <caption style="font-weight: bold;">Date: <xsl:value-of select="date"/></caption>
     <thead>
      <tr>
        <th>Name</th> 
        <th>Amount</th>
        <th>Cost</th>
        <th>Total</th>
        <th>Participants</th>        
      </tr>             
     </thead>
     <tbody>
       <xsl:apply-templates select="key('tableByBillDate',date)/product"/>
     </tbody>
    </table>      
  </xsl:template>

  <xsl:template match="product">
            <tr>
              <td><xsl:value-of select="name"/></td>
              <td><xsl:value-of select="amount"/></td>
              <td><xsl:value-of select="prize"/></td>
              <td>Calculated with Javascript</td>
              <td><xsl:value-of select="participant"/></td>   
           </tr>      
  </xsl:template>


  <xsl:template match="/">
    <html>
      <head>
        <title>.NET XSLT Fiddle Example</title>
            <style>
        table {
          font-family: arial, sans-serif;
          border-collapse: collapse;
          width: 100%;
        }

        td, th {
          border: 1px solid #dddddd;
          text-align: left;
          padding: 8px;
        }

        tr:nth-child(even) {
            background-color: #dddddd;
        }   

        caption {
          display: table-caption;
          text-align: center;
        }
    </style>
      </head>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/3MvmXis

...