Обратный порядок без xsl: sort - PullRequest
0 голосов
/ 03 мая 2011

В моем xsl есть какая-то проблема, я не знаю причину, по которой я хочу использовать apply-templates для обращения различных последовательностей XML без xsl: sort;Например: ниже приведен ввод

<book title="XML">
  <author first="P" />
   <chapter title="A">
     <section title="A.1" />
     <section title="A.2">
       <section title="A.2.1" />
       <section title="A.2.2" />
     </section>
     <section title="A.3">
       <section title="A.3.1" />
    </section>
  </chapter>
  <chapter title="B">
    <section title="B.1" />
    <section title="B.2">
      <section title="B.2.1" />
      <section title="B.2.2" />
    </section>
  </chapter>
</book>

Я хочу получить вывод наподобие этого: это мой xsl.

<?xml version="1.0" encoding="UTF-8"?>
<book title="XML">
   <author first="P"/>
   <chapter title="A">
      <section title="A.1">
        <section title="A.3.1"/>
      </section>
      <section title="A.2">
        <section title="A.2.2"/>
        <section title="A.2.1"/>
      </section>
      <section title="A.1"/>
   </chapter>
   <chapter title="B">
      <section title="B.2">
         <section title="B.2.2"/>
         <section title="B.2.1"/>
      </section>
      <section title="B.1"/>
   </chapter>
  </book>

Да, разделы были перевернуты, но главыне.ниже мой xsl, здесь есть какая-то проблема, не могли бы вы помочь мне найти его ??

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
  <xsl:output method="xml"  version="1.0" encoding="UTF-8" indent ="yes"/>
  <xsl:template match="/">
    <xsl:apply-templates/>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>

  <xsl:template match="book">
    <xsl:copy>
      <xsl:sequence select="@title"/>
      <xsl:sequence select="author"/>
      <xsl:apply-templates select="chapter">
        <xsl:with-param name="seq" select="section"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <xsl:template match ="chapter|section" as="element()">
    <xsl:param name="seq" as="element(section)*"/>
    <xsl:copy>
         <xsl:sequence select="@title"/>
        <xsl:if test="not(empty($seq))">
             <xsl:apply-templates select="chapter">
                <xsl:with-param name="seq" select="$seq"/>
            </xsl:apply-templates>
            <xsl:apply-templates select="$seq[1]"/>
        </xsl:if>
    </xsl:copy>
  </xsl:template>
</xsl:transform>

Ответы [ 2 ]

1 голос
/ 04 мая 2011

Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()[1]|@*"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="section">
        <xsl:apply-templates select="following-sibling::node()[1]"/>
        <xsl:copy>
            <xsl:apply-templates select="node()[1]|@*"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Вывод:

<book title="XML">
    <author first="P"></author>
    <chapter title="A ">
        <section title="A.3 ">
            <section title="A.3.1"></section>
        </section>
        <section title="A.2">
            <section title="A.2.2"></section>
            <section title="A.2.1"></section>
        </section>
        <section title="A.1"></section>
    </chapter>
    <chapter title="B">
        <section title="B.2">
            <section title="B.2.2"></section>
            <section title="B.2.1"></section>
        </section>
        <section title="B.1"></section>
    </chapter>
</book>
0 голосов
/ 03 мая 2011

Как насчет этого?

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml"  version="1.0" encoding="UTF-8" indent ="yes"/>

  <xsl:template match ="chapter|section">
    <xsl:copy>
        <xsl:copy-of select="@*" />
        <xsl:for-each select="*">
            <xsl:sort select="position()" data-type="number" order="descending"/>
            <xsl:apply-templates select="." />
        </xsl:for-each>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*">
    <xsl:copy>
        <xsl:copy-of select="@*" />
        <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
</xsl:transform>

Несколько замечаний:

  • match = "*" шаблон: это обеспечивает поведение по умолчанию для элементов, которые нам просто нужно скопировать с атрибутами и затем обработать дочерние элементы. Это заменяет ваши шаблоны "book" и "/" и не дает предположений о том, что в нем содержится. Это означает, что теперь мы можем сосредоточиться на предоставлении шаблонов для элементов, на которые не распространяется поведение по умолчанию.
  • for-each: Здесь происходит волшебство, перечисляя дочерние элементы, которые мы затем сортируем в порядке убывания на основе позиции перед обработкой их с применением шаблонов.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...