xsl, xml group by - PullRequest
       10

xsl, xml group by

0 голосов
/ 26 февраля 2012

Эй, у меня есть xollowing-файл foolowing:

<?xml version="1.0"?>
 <accidents>
 <accident>
   <org>1</org>
   <com>194</com>
   <dep>010</dep>
   <grav>0.64</grav>
 </accident>
 <accident>
   <org>1</org>
   <com>194</com>
   <dep>420</dep>
   <grav>0.54</grav>
 </accident>
 <accident>
   <org>1</org>
   <com>44</com>
   <dep>010</dep>
   <grav>0.4</grav>
</accident>
</accidents>

И я хочу применить xslt 1.0, чтобы количество несчастных случаев по dep: вывод должен быть в виде html-страницы, например:*

 <table> <thead> <tr> <th>420</th> <th>010</th> </tr> </thead> <tbody> <tr> 
   <th>accidents</th> <td>1</td> <td>2</td> </tr> </tbody> </table>

спасибо, обратите внимание, я использую php5

Ответы [ 2 ]

1 голос
/ 27 февраля 2012

Вы можете использовать почти тот же ответ, что и на предыдущий вопрос :

<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>

     <xsl:key name="kAccByDept" match="accident" use="dep"/>

     <xsl:template match="/*">
      <html>
       <table border="1">
         <thead>
           <tr>
            <th>deps:</th>
             <xsl:apply-templates/>
           </tr>
         </thead>
         <tbody>
            <tr>
             <th>accidents:</th>
             <xsl:apply-templates mode="count"/>
           </tr>
         </tbody>
       </table>
      </html>
     </xsl:template>

     <xsl:template match=
      "accident
        [generate-id()
        =
         generate-id(key('kAccByDept', dep)[1])
         ]">
         <td><xsl:value-of select="dep"/></td>
     </xsl:template>
     <xsl:template mode="count" match=
      "accident
        [generate-id()
        =
         generate-id(key('kAccByDept', dep)[1])
         ]">
         <td><xsl:value-of select="count(key('kAccByDept', dep))"/></td>
     </xsl:template>
     <xsl:template match="text()"/>
     <xsl:template match="text()" mode="count"/>
</xsl:stylesheet>

Когда это преобразование применяется к предоставленному документу XML :

<accidents>
    <accident>
        <org>1</org>
        <com>194</com>
        <dep>010</dep>
        <grav>0.64</grav>
    </accident>
    <accident>
        <org>1</org>
        <com>194</com>
        <dep>420</dep>
        <grav>0.54</grav>
    </accident>
    <accident>
        <org>1</org>
        <com>44</com>
        <dep>010</dep>
        <grav>0.4</grav>
    </accident>
</accidents>

получен правильный результат (с добавлением «deps:» в заголовок для достижения правильного выравнивания):

<html>
   <table border="1">
      <thead>
         <tr>
            <th>deps:</th>
            <td>010</td>
            <td>420</td>
         </tr>
      </thead>
      <tbody>
         <tr>
            <th>accidents:</th>
            <td>2</td>
            <td>1</td>
         </tr>
      </tbody>
   </table>
</html>

Вещи становятся болееИнтересно, если есть другие события, кроме несчастных случаев и отделов без происшествий.Предположим, у нас теперь есть этот XML-документ :

<events>
    <accidents>
        <accident>
            <org>1</org>
            <com>194</com>
            <dep>010</dep>
            <grav>0.64</grav>
        </accident>
        <accident>
            <org>1</org>
            <com>194</com>
            <dep>420</dep>
            <grav>0.54</grav>
        </accident>
        <accident>
            <org>1</org>
            <com>44</com>
            <dep>010</dep>
            <grav>0.4</grav>
        </accident>
    </accidents>
    <achievements>
        <achievement>
            <org>1</org>
            <com>194</com>
            <dep>002</dep>
            <grav>0.64</grav>
        </achievement>
        <achievement>
            <org>1</org>
            <com>194</com>
            <dep>420</dep>
            <grav>0.54</grav>
        </achievement>
        <achievement>
            <org>1</org>
            <com>44</com>
            <dep>011</dep>
            <grav>0.4</grav>
        </achievement>
    </achievements>
</events>

Вот опять преобразование, которое корректно производит все различные отделы и их количество несчастных случаев :

<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>

     <xsl:key name="kAccByDept" match="accident" use="dep"/>
     <xsl:key name="kDepByCode" match="dep" use="."/>

     <xsl:variable name="vDeps" select=
     "/*/*/*/dep
             [generate-id()
             =
              generate-id(key('kDepByCode', .)[1])
             ]
     "/>

     <xsl:template match="/*">
      <html>
       <table border="1">
         <thead>
           <tr>
            <th>deps:</th>
             <xsl:apply-templates select="$vDeps"/>
           </tr>
         </thead>
         <tbody>
            <tr>
             <th>accidents:</th>
             <xsl:apply-templates select="$vDeps" mode="acc"/>
           </tr>
         </tbody>
       </table>
      </html>
     </xsl:template>

     <xsl:template match="dep">
         <td><xsl:value-of select="."/></td>
     </xsl:template>

     <xsl:template match="dep" mode="acc">
         <td><xsl:value-of select="count(key('kAccByDept', .))"/></td>
     </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к приведенному выше XML-документу, оно дает правильный желаемый результат :

<html>
   <table border="1">
      <thead>
         <tr>
            <th>deps:</th>
            <td>010</td>
            <td>420</td>
            <td>002</td>
            <td>011</td>
         </tr>
      </thead>
      <tbody>
         <tr>
            <th>accidents:</th>
            <td>2</td>
            <td>1</td>
            <td>0</td>
            <td>0</td>
         </tr>
      </tbody>
   </table>
</html>

ОБНОВЛЕНИЕ : В комментарии ОП спросилтакже иметь сумму «com» ​​на отдел.

Преобразование необходимо изменить лишь незначительно :

<xsl:stylesheet version="1.0"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
         <xsl:output omit-xml-declaration="yes" indent="yes"/>
         <xsl:strip-space elements="*"/>

         <xsl:key name="kAccByDept" match="accident" use="dep"/>
         <xsl:key name="kDepByCode" match="dep" use="."/>

         <xsl:variable name="vDeps" select=
         "/*/*/*/dep
                 [generate-id()
                 =
                  generate-id(key('kDepByCode', .)[1])
                 ]
         "/>

         <xsl:template match="/*">
          <html>
           <table border="1">
             <thead>
               <tr>
                <th>deps:</th>
                 <xsl:apply-templates select="$vDeps"/>
               </tr>
             </thead>
             <tbody>
                <tr>
                 <th>accidents:</th>
                 <xsl:apply-templates select="$vDeps" mode="acc"/>
               </tr>
                <tr>
                 <th>coms:</th>
                 <xsl:apply-templates select="$vDeps" mode="com"/>
               </tr>
             </tbody>
           </table>
          </html>
         </xsl:template>

         <xsl:template match="dep">
             <td><xsl:value-of select="."/></td>
         </xsl:template>

         <xsl:template match="dep" mode="acc">
             <td><xsl:value-of select="count(key('kAccByDept', .))"/></td>
         </xsl:template>
         <xsl:template match="dep" mode="com">
             <td><xsl:value-of select="sum(key('kAccByDept', .)/com)"/></td>
         </xsl:template>
</xsl:stylesheet>

Теперь при применении ктот же XML-документ (выше), снова выдается желаемый ответ :

<html>
   <table border="1">
      <thead>
         <tr>
            <th>deps:</th>
            <td>010</td>
            <td>420</td>
            <td>002</td>
            <td>011</td>
         </tr>
      </thead>
      <tbody>
         <tr>
            <th>accidents:</th>
            <td>2</td>
            <td>1</td>
            <td>0</td>
            <td>0</td>
         </tr>
         <tr>
            <th>coms:</th>
            <td>238</td>
            <td>194</td>
            <td>0</td>
            <td>0</td>
         </tr>
      </tbody>
   </table>
</html>
0 голосов
/ 26 февраля 2012

Использование:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:key name="k" match="accident" use="dep"/>

  <xsl:template match="/accidents">
    <xsl:variable name="accidents" select="accident[generate-id() 
                  = generate-id(key('k', dep))]"/>

    <table>
      <thead>
        <tr>
          <xsl:for-each select="$accidents">
            <th>
              <xsl:value-of select="dep"/>
            </th>
          </xsl:for-each>
        </tr>
      </thead>
      <tbody>
        <tr>
          <xsl:for-each select="$accidents">
            <td>
              <xsl:value-of select="count(key('k', dep))"/>
            </td>
          </xsl:for-each>
        </tr>
      </tbody>
    </table>
  </xsl:template>

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