XSL XML Looping - PullRequest
       3

XSL XML Looping

0 голосов
/ 06 декабря 2011

У меня есть XML-файл, который я использую XSL для преобразования в HTML-страницу.Я хотел бы перебрать файл XML, который содержит много родительских узлов, а затем перебрать дочерние узлы и отобразить результат в таблице HTML.

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

Может кто-нибудь пролить немного света на это.

XML:

<AdminReports xmlns="30/11/2011 09:25:58">
    <AdminReport ID="1">
        <DataSourceInformation DataSourceID="12" Value="DSI_50"/>
    </AdminReport>
    <AdminReport ID="2">
        <DataSourceInformation DataSourceID="23" Value="DSI_30"/>
    </AdminReport>
    <AdminReport ID="3">
        <DataSourceInformation DataSourceID="34" Value="DSI_20"/>
    </AdminReport>
</AdminReports>

XSL:

  <table border="1" cellspacing="2" width="800" bgcolor="white">
 <xsl:for-each select="/*/*[name()='AdminReport']">
       <tr bgcolor="9acd32">
       <table><th>Admin Report Num:</th></table>
       <table><th><xsl:value-ofselect="@ID"/>   </th></table>
    </tr>
    <tr>    
     <xsl:for-each select="/*/*/*[name()='DataSourceInformation']"> 
      <table><th>Data Report ID:</th></table>
              <table><th><xsl:value-of select="@DataSourceID"/></th></table>
     </xsl:for-each>
     </tr>
    </xsl:for-each>
</table>

Ответы [ 4 ]

2 голосов
/ 06 декабря 2011

Это можно сделать более аккуратно, используя шаблоны вместо for-each:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                              xmlns:x="30/11/2011 09:25:58">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:template match="/">
        <table border="1" cellspacing="2" width="800" bgcolor="white">
            <xsl:apply-templates/>
        </table>
    </xsl:template>
    <xsl:template match="x:AdminReport">
        <tr bgcolor="9acd32">
            <table><th>Admin Report Num:</th></table>
            <table><th><xsl:value-of select="@ID"/></th></table>
        </tr>
        <tr><xsl:apply-templates/></tr>
    </xsl:template>
    <xsl:template match="x:DataSourceInformation">
        <table><th>Data Report ID:</th></table>
        <table><th><xsl:value-of select="@DataSourceID"/></th></table>
    </xsl:template>
</xsl:stylesheet>

Примечания :

  • Каждый раздел получает свой собственный шаблон,который более четко структурирует таблицу стилей
  • Будет проще обрабатывать новые элементы в будущем, используя этот подход
  • Я зарегистрировал ваше пространство имен с префиксом x, чтобы я мог ссылаться на такие элементы, как x:DataSourceInformation вместо *[name()='DataSourceInformation']
  • for-each редко требуется в XSLT;шаблоны почти всегда являются более естественным решением
  • Если вы настаиваете на for-each, посмотрите на ответ @ GSerg
1 голос
/ 07 декабря 2011

Проще представить XSLT как механизм декларативного сопоставления шаблонов. Посмотрите на элементы xsl: template и xsl: apply-template в этом примере. С наилучшими пожеланиями!

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns="30/11/2011 09:25:58">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/ns:AdminReports">
    <table border="1" cellspacing="2" width="800" bgcolor="white">
      <xsl:apply-templates select="ns:AdminReport"/>
    </table>
  </xsl:template>

  <xsl:template match ="ns:AdminReport">
      <tr bgcolor="9acd32">
        <th>Admin Report Num:</th>
        <th>
          <xsl:value-of select="@ID"/>
        </th>
      </tr>
      <tr>
        <xsl:apply-templates select="ns:DataSourceInformation" />
      </tr>
  </xsl:template>

  <xsl:template match="ns:DataSourceInformation" >
      <table>
        <th>Data Report ID:</th>
      </table>
      <table>
        <th>
          <xsl:value-of select="@DataSourceID"/>
        </th>
      </table>
  </xsl:template>

</xsl:stylesheet>
1 голос
/ 06 декабря 2011

Ты слишком усложняешь это.

select относительно текущего узла контекста:

<table border="1" cellspacing="2" width="800" bgcolor="white">
    <xsl:for-each select="/*/*[name()='AdminReport']">
       <tr bgcolor="9acd32">
       <table><th>Admin Report Num:</th></table>
       <table><th><xsl:value-of select="@ID"/>   </th></table>
       </tr>
       <tr> 
       <xsl:for-each select="*[name()='DataSourceInformation']">    
           <table><th>Data Report ID:</th></table>
           <table><th><xsl:value-of select="@DataSourceID"/></th></table>
       </xsl:for-each>
       </tr>
     </xsl:for-each>
</table>
0 голосов
/ 06 декабря 2011

Нет пробела между значением-из & выберите

<xsl:value-ofselect="@ID"/>

должно быть <xsl:value-of select="@ID"/>

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