Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > XML, XSL > помогите с xslt преобразованием?


Автор: seeker 30.11.2005, 08:52
есть xml, примерно такой:

Код

<div>
-<tag1/>
</div>
<div>
-<tag2/>
</div>
<div>
-<tag3/>
</div>
<othertag/>
<div>
-<tag4/>
</div>


нужно получить примерно такой:

Код

<table>
-<tr>
--<td>
---<tag1/>
--</td>
-</tr>
-<tr>
--<td>
---<tag2/>
--</td>
-</tr>
-<tr>
--<td>
---<tag3/>
--</td>
-</tr>
</table>
<othertag/>
</table>
-<tr>
--<td>
---<tag4/>
--</td>
-</tr>
</table>


пояснение:
все элементы <div/> определённого уровня идущие друг за другом нужно поместить в таблицу.
другие элементы в таблицу попасть не должны.
порядок элементов должен быть сохранён.

внимание вопрос:
можно ли написать такое xslt преобразование, и если можно, то как?
М
 
Пользуемся кнопкой "код"!

Автор: 3,14 30.11.2005, 11:23
XML:
Код

<?xml version="1.0" encoding="windows-1251"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>

<divs> 
  <div>
   <tag1/>
  </div>
  <div>
   <tag2/>
  </div>
  <div>
   <tag3/>
  </div>
  <othertag/>
  <div>
   <tag4/>
  </div>
</divs> 


XSL:
Код

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

<xsl:template match="/divs">
  <table>
  <xsl:for-each select="div">
     <tr>
       <td>
           <xsl:for-each select="*">
               <xsl:copy>
                   <xsl:apply-templates select="node()|@*"/>
               </xsl:copy>
           </xsl:for-each>
       </td>
     </tr>
  </xsl:for-each>
  </table>
</xsl:template>

<xsl:template match="*|@*">
  <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
</xsl:template>


</xsl:stylesheet>


Результат:
Код

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

<table>
    <tr>
        <td>
            <tag1 />
        </td>
    </tr>
    <tr>
        <td>
            <tag2 />
        </td>
    </tr>
    <tr>
        <td>
            <tag3 />
        </td>
    </tr>
    <tr>
        <td>
            <tag4 />
        </td>
    </tr>
</table>

Автор: seeker 30.11.2005, 13:01
ето всё конечно хорошо, но нужно чтобы получилось две таблицы, разделённые <othertag/>

Автор: 3,14 30.11.2005, 14:52
Нет, такого по-моему средствами XSLT уже не сделаешь.

Автор: maxim1000 30.11.2005, 17:29
немного неопрятно, но вроде работает...
xml:
Код

<?xml version="1.0" encoding="windows-1251"?>
<?xml-stylesheet type="text/xsl" href="qqq.xsl"?>

<divs> 
  <div>
   1
  </div>
  <div>
   2
  </div>
  <div>
   3
  </div>
  <othertag/>
  <div>
   4
  </div>
</divs> 

xsl:
Код

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

  <xsl:template match="/divs">
    <xsl:for-each select="*">
      <xsl:if test="self::othertag">
        table begin<br/>
        <xsl:variable name="index" select="position()"/>
        <xsl:for-each select="../*[$index > position()]">
          <xsl:apply-templates/><br/>
        </xsl:for-each>
        table end<br/>
        next table begin<br/>
        <xsl:for-each select="../*[position() > $index]">
          <xsl:apply-templates/><br/>
        </xsl:for-each>
        next table end<br/>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

результат:
Код

table begin
1 
2 
3 
table end
next table begin
4 
next table end

P.S.
теги убрал, потому как неудобно было отлаживать... думаю, с заточкой под реальный вариант проблем возникнуть не должно
P.P.S.
если будет несколько тегов othertag - можно расширять этот вариант в сторону рекурсии...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)