На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: ANDLL
  
> Вывод элементов документа вместе с атрибутами.ХSLT , для документа произвольной структури, чтобы одинаковые элементы выводились один раз
    Доброго времени суток!
    Нужно составить "универсальную" таблицу стилей ХSLT, которая для xml-документа произвольной структуры выведет список элементов вместе с атрибутами так, чтобы елементы одинаковой структуры( с одинаковым именем и набором атрибутов) встречались в списке только один раз. Изгалялся и так, и сяк, пока родил следующее:
    ExpandedWrap disabled
      <?xml version="1.0" encoding="ISO-8859-1"?>
      <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
       
      <xsl:template match="/">
      <HTML>
      <title></title>
      <body>  
       
      <xsl:call-template name="recurs">
          <xsl:with-param name="nextnodes" select="child::*" />
      </xsl:call-template>
       
      </body>
      </HTML>
      </xsl:template>
       
      <xsl:template name="recurs">
      <xsl:param name="nextnodes" />
      <xsl:for-each select="$nextnodes">
          <xsl:if test="not(name(current())=name(following::*)) and not(name(current())=name(following::*/descendant::*)) and not(name(current())=name(following-sibling::*))">
              Element <b><xsl:value-of select="name(current())" /></b> has attributes <text> </text>
              <xsl:for-each select="@*">
              <xsl:if test="position()=last()">
              <b><xsl:value-of select="name(current())" /><text>.</text></b>
              </xsl:if>
              <xsl:if test="position()!=last()">
                  <b><xsl:value-of select="name(current())" /><text>,  </text></b>
              </xsl:if>
              </xsl:for-each>
              <br /><br />
          </xsl:if>
          <xsl:call-template name="recurs">
              <xsl:with-param name="nextnodes" select="child::*" />
          </xsl:call-template>
          
      </xsl:for-each>
      </xsl:template>
       
      </xsl:stylesheet>


    Вот такой тест-кейз обрабатывает как надо:
    ExpandedWrap disabled
      <?xml version="1.0" encoding="utf-8"?>
      <?xml-stylesheet type="text/xsl" href="task3_4a.xsl"?>
      <catalog subnodes="2">
       
      <cities country="England">
      <city name="London" region="London" population="10000" />
      <city name="New South Wales" region="Wales" population="800000" />
       
      </cities>
       
      <articles country="USA">
      <article name="My lovely country" src="art1.txt" />
      <article name="Places to visit" src="art2.txt" />
      <article name="Article 3" src="art3.txt" />
      </articles>
       
      <books>
      <book title="Warhammer">
       </book>
      <book title="We fought for truth">
      </book>
      </books>
       
      <scientifics  atr = " ">
       <book title="Warhammer">
      </book>
      </scientifics>
       
      </catalog>

    Вывод собственно такой:
    Element catalog has attributes subnodes.

    Element cities has attributes country.

    Element city has attributes name, region, population.

    Element articles has attributes country.

    Element article has attributes name, src.

    Element books has attributes

    Element scientifics has attributes atr.

    Element book has attributes title.

    А на таком тесте происходит фейл:
    ExpandedWrap disabled
      <?xml version="1.0" encoding="utf-8"?>
      <?xml-stylesheet type="text/xsl" href="task3_4a.xsl"?>
      <catalog subnodes="2">
       
      <cities country="England">
      <city name="London" region="London" population="10000" />
      <city name="New South Wales" region="Wales" population="800000" />
       
      </cities>
       
      <articles country="USA">
      <article name="My lovely country" src="art1.txt" />
      <article name="Places to visit" src="art2.txt" />
      <article name="Article 3" src="art3.txt" />
      </articles>
       
      <books>
      <book title="Warhammer">
      <article name="My lovely country" src="art1.txt" />
       </book>
      <book title="We fought for truth">
      <article name="My lovely country" src="art1.txt" />
      </book>
      </books>
       
      <scientifics  atr = " ">
       <book title="Warhammer">
       
       <article name="My lovely country" src="art1.txt" />
       </book>
       
      </scientifics>
       
      </catalog>


    В списке дваждый появляется Element article has attributes name, src. :wacko:
    Хотелось бы как-то это победить, но идей пока нет...
      ExpandedWrap disabled
        <?xml version="1.0" encoding="ISO-8859-1"?>
        <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
            <xsl:template match="/">
                <HTML>
                    <title/>
                    <body>
                        <xsl:apply-templates select=".//*" mode="test-all-nodes"/>
                    </body>
                </HTML>
            </xsl:template>
         
            <xsl:template match="*" mode="test-all-nodes">
                <xsl:if test="not(preceding::*[name(.)=name(current())])">
                    Element <b><xsl:value-of select="name(current())" /></b> has attributes: <xsl:apply-templates select="@*" mode="print-attributes"/>
                </xsl:if>
         
                <xsl:if test="preceding::*[name(.)=name(current())]">
                    <xsl:apply-templates select="." mode="test-attributes"/>
                </xsl:if>
            </xsl:template>
         
            <xsl:template match="*" mode="test-attributes">
                <xsl:for-each select="preceding::*[name(.)=name(current())]">
                <!-- влом -->
                </xsl:for-each>
            </xsl:template>
         
            <xsl:template match="@*[position()=last()]" mode="print-attributes">
                <b><xsl:value-of select="name(current())" />.</b>
            </xsl:template>
         
            <xsl:template match="@*" mode="print-attributes">
                <b><xsl:value-of select="name(current())" />, </b>
            </xsl:template>
         
        </xsl:stylesheet>
        Спасибо :)
        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
        0 пользователей:


        Рейтинг@Mail.ru
        [ Script execution time: 0,0248 ]   [ 15 queries used ]   [ Generated: 14.05.24, 18:19 GMT ]