2010-08-11 3 views
1

У меня есть две проблемы с ниже код, который мне нужно фиксирование справки:Нужна помощь фиксируя XSLT документ

1) Она не включает в себя корневой узел, когда возвращать результаты из выражения XPath. (Я пробовал пару вещей, но это еще хуже ...)

2) Мне нужна помощь в исправлении форматирования результатов. Мне нужны те же узлы с теми же атрибутами, которые перечислены под одним заголовком, вместо заголовка для каждого результата. Раньше у меня был similar question, но теперь, когда проблемы с кодом были исправлены, я не могу заставить свои заголовки работать правильно, не ставя под угрозу результаты.

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

Вот некоторые намеренно несовместимым фиктивная XML Я тестирую с:

<pets name="myPets" NUM="2"> 
    <dog name="allMyDogs" NUM="5"> 
     <dog name="Frank" cute="yes" color"brown" type="Lab" NUM="3"/> 
     <dog name="Frank" NUM="3"/> 
     <dog name="Spot" NUM="4"/> 
     <dog name="Rover" cute="yes" NUM="1"/> 
     <dog name="Rupert" cute="yes" type="Pug" color="black" NUM="6"/> 
     <cat name="Lucy" cute="yes" NUM="4"/> 
    </dog> 
    <cat name="allMyCats" NUM="4"> 
     <cat name="Simba" cute="yes" NUM="4"/> 
     <cat name="Princess" cute="no" color="black" NUM="5"/> 
     <cat name="Fluffy" cute="yes" color="grey" NUM="1"/> 
     <cat name="Lucy" cute="yes" color="brown" NUM="3"> 
      <cat name="Lucy" cute="no" NUM="35"/> 
      <cat name="Lucy" cute="yes" purrs="yes" NUM="6"/> 
     </cat> 
     <cat name="Lucy"cute="no" color="grey" NUM="1"/> 
     <dog name="Rover" cute="yes" NUM="24"/> 
    </cat> 
    <cat name="Lucy" NUM="9"/> 
    <dog name="Rupert Jr" cute="yes" type="Pug" color="black" NUM="0"/> 
</pets> 

А вот код XSLT:

<xsl:key name="elem_key" match="elem" use="concat(@key, .)" /> 

    <xsl:variable name="all_data"> 
     <xsl:apply-templates select="*//*"> 
      <xsl:sort select="name()" /> 
     </xsl:apply-templates> 
    </xsl:variable> 

    <xsl:template match="//*[@NUM&lt;=4]"> 
     <elem key="{name()}"> 
      <xsl:copy-of select="@*" /> 
      <xsl:for-each select="@*"> 
       <xsl:sort select="name()" /> 
       <attribute>|<xsl:value-of select="name()" />|</attribute> 
      </xsl:for-each> 
     </elem> 
    </xsl:template> 

    <xsl:template match="/"> 
     <html> 
      <body> 
       <xsl:for-each select="msxsl:node-set($all_data)"> 
        <xsl:for-each select="*[generate-id()=generate-id(key('elem_key',concat(@key, .))[1])]"> 
         <table > 
          <tr> 
           <td>Element Name</td> 
           <xsl:for-each select="*"> 
            <td> 
             <xsl:value-of select="translate(.,'|','')" /> 
            </td> 
           </xsl:for-each> 
          </tr> 
          <xsl:for-each select="key('elem_key', concat(@key, .))"> 
           <xsl:variable name="curr_elem" select="." /> 
           <tr> 
            <td> 
             <xsl:value-of select="@key" /> 
            </td> 
            <xsl:for-each select="*"> 
             <td > 
              <xsl:value-of select="$curr_elem/@*[name()=translate(current(),'|','')]" /> 
             </td> 
            </xsl:for-each> 
           </tr> 
          </xsl:for-each> 
         </table> 
         <p /> 
        </xsl:for-each> 
       </xsl:for-each> 
      </body> 
     </html> 
    </xsl:template> 

И желаемое форматирование для вывода:

Element Name Name NUM 
pets   myPets 2 

Element Name Name  Cute Color NUM Type 
dog   Frank  yes brown 3 Lab 
dog   Rupert Jr yes black 0 Pug 

Element Name Name NUM 
dog   Frank 3 
dog   Spot 4 

Element Name Name Cute NUM 
dog   Rover yes 1 

Element Name Name Cute NUM 
cat   Lucy yes 4 
cat   Simba yes 4 

Element Name Name  NUM 
cat   allMyCats 4 

Element Name Name Color Cute NUM 
cat   Fluffy grey yes 1 
cat   Lucy brown yes 3 
cat   Lucy grey no 1 

Спасибо! :) Дайте мне знать, если мне нужно что-нибудь прояснить!

+0

Вы забыли указать, что именно вы хотите получить от преобразования. Пожалуйста. –

+0

@ Dimitre: Спасибо, что указали это. Обновлен с желаемым выходом. – developer

+0

Я думаю, что мой ответ теперь содержит нужное вам решение (+1). :) –

ответ

2

Это преобразование имеет все указанные проблемы фиксированной:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
exclude-result-prefixes="msxsl"> 

    <xsl:key name="elem_key" match="elem" use="." /> 

    <xsl:key name="elem_key2" match="elem" 
    use="concat(@key, @name, .)" /> 

    <xsl:variable name="all_data"> 
     <xsl:apply-templates select="//*[@NUM&lt;=4]"> 
      <xsl:sort select="name()" /> 
     </xsl:apply-templates> 
    </xsl:variable> 

    <xsl:template match="*"> 
     <elem key="{name()}"> 
      <xsl:copy-of select="@*" /> 
      <xsl:for-each select="@*"> 
       <xsl:sort select="name()" /> 
       <attribute>|<xsl:value-of select="name()" />|</attribute> 
      </xsl:for-each> 
     </elem> 
    </xsl:template> 

    <xsl:template match="/"> 
     <html> 
      <body> 
       <xsl:for-each select="msxsl:node-set($all_data)"> 
        <xsl:for-each select= 
        "*[generate-id() 
         = 
         generate-id(key('elem_key',.)[1]) 
         ]"> 
         <table > 
          <tr> 
           <td>Element Name</td> 
           <xsl:for-each select="*"> 
            <td> 
             <xsl:value-of select= 
              "translate(.,'|','')" /> 
            </td> 
           </xsl:for-each> 
          </tr> 
          <xsl:for-each select="key('elem_key',.)"> 
           <xsl:variable name="curr_elem" select="." /> 
           <tr> 
            <td> 
             <xsl:value-of select="@key" /> 
            </td> 
            <xsl:for-each select="*"> 
             <td > 
              <xsl:value-of select= 
              "$curr_elem/@* 
               [name() 
               = 
               translate(current(), 
                 '|', 
                 '' 
                 ) 
               ]" /> 
             </td> 
            </xsl:for-each> 
           </tr> 
          </xsl:for-each> 
         </table> 
         <p /> 
        </xsl:for-each> 
       </xsl:for-each> 
      </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 

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

<pets name="myPets" NUM="2"> 
    <dog name="allMyDogs" NUM="5"> 
     <dog name="Frank" cute="yes" color="brown" type="Lab" NUM="3"/> 
     <dog name="Frank" NUM="3"/> 
     <dog name="Spot" NUM="4"/> 
     <dog name="Rover" cute="yes" NUM="1"/> 
     <dog name="Rupert" cute="yes" type="Pug" color="black" NUM="6"/> 
     <cat name="Lucy" cute="yes" NUM="4"/> 
    </dog> 
    <cat name="allMyCats" NUM="4"> 
     <cat name="Simba" cute="yes" NUM="4"/> 
     <cat name="Princess" cute="no" color="black" NUM="5"/> 
     <cat name="Fluffy" cute="yes" color="grey" NUM="1"/> 
     <cat name="Lucy" cute="yes" color="brown" NUM="3"> 
      <cat name="Lucy" cute="no" NUM="35"/> 
      <cat name="Lucy" cute="yes" purrs="yes" NUM="6"/> 
     </cat> 
     <cat name="Lucy" cute="no" color="grey" NUM="1"/> 
     <dog name="Rover" cute="yes" NUM="24"/> 
    </cat> 
    <cat name="Lucy" NUM="9"/> 
    <dog name="Rupert Jr" cute="yes" type="Pug" color="black" NUM="0"/> 
</pets> 

разыскиваемый результат получают:

<html> 
    <body> 
     <table> 
      <tr> 
       <td>Element Name</td> 
       <td>cute</td> 
       <td>name</td> 
       <td>NUM</td> 
      </tr> 
      <tr> 
       <td>cat</td> 
       <td>yes</td> 
       <td>Lucy</td> 
       <td>4</td> 
      </tr> 
      <tr> 
       <td>cat</td> 
       <td>yes</td> 
       <td>Simba</td> 
       <td>4</td> 
      </tr> 
      <tr> 
       <td>dog</td> 
       <td>yes</td> 
       <td>Rover</td> 
       <td>1</td> 
      </tr> 
     </table> 
     <p></p> 
     <table> 
      <tr> 
       <td>Element Name</td> 
       <td>name</td> 
       <td>NUM</td> 
      </tr> 
      <tr> 
       <td>cat</td> 
       <td>allMyCats</td> 
       <td>4</td> 
      </tr> 
      <tr> 
       <td>dog</td> 
       <td>Frank</td> 
       <td>3</td> 
      </tr> 
      <tr> 
       <td>dog</td> 
       <td>Spot</td> 
       <td>4</td> 
      </tr> 
      <tr> 
       <td>pets</td> 
       <td>myPets</td> 
       <td>2</td> 
      </tr> 
     </table> 
     <p></p> 
     <table> 
      <tr> 
       <td>Element Name</td> 
       <td>color</td> 
       <td>cute</td> 
       <td>name</td> 
       <td>NUM</td> 
      </tr> 
      <tr> 
       <td>cat</td> 
       <td>grey</td> 
       <td>yes</td> 
       <td>Fluffy</td> 
       <td>1</td> 
      </tr> 
      <tr> 
       <td>cat</td> 
       <td>brown</td> 
       <td>yes</td> 
       <td>Lucy</td> 
       <td>3</td> 
      </tr> 
      <tr> 
       <td>cat</td> 
       <td>grey</td> 
       <td>no</td> 
       <td>Lucy</td> 
       <td>1</td> 
      </tr> 
     </table> 
     <p></p> 
     <table> 
      <tr> 
       <td>Element Name</td> 
       <td>color</td> 
       <td>cute</td> 
       <td>name</td> 
       <td>NUM</td> 
       <td>type</td> 
      </tr> 
      <tr> 
       <td>dog</td> 
       <td>brown</td> 
       <td>yes</td> 
       <td>Frank</td> 
       <td>3</td> 
       <td>Lab</td> 
      </tr> 
      <tr> 
       <td>dog</td> 
       <td>black</td> 
       <td>yes</td> 
       <td>Rupert Jr</td> 
       <td>0</td> 
       <td>Pug</td> 
      </tr> 
     </table> 
     <p></p> 
    </body> 
</html> 
+0

@Dimitre: ** хмм .. Я думаю, что в результатах есть дубликаты. ** Я думаю, что осталось только 12 результатов. О, и изначально мне нужны разные узлы (cat vs dog) под разными заголовками, но я думаю, что я мог бы быть в порядке с тем, как вы его отображали (гораздо более кратким). Мне просто нужно убедиться, что он остается отсортированным по имени элемента. – developer

+0

@ Dimitre: +1 за весь ответ, который вы получили от этого проекта. Ja! – 2010-08-11 21:21:35

+0

@iHeartGreek: Спасибо, что заметили это. Теперь я исправил эту последнюю проблему, и теперь преобразование дает именно желаемый результат. –

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