XSL-преобразование произвольной структуры списка - PullRequest
0 голосов
/ 28 августа 2010

Я пытаюсь преобразовать содержимое индекса файла CHM (справки Microsoft HTML), который содержит информацию о структуре в очень произвольных списках HTML, с помощью XSL (см. Первый фрагмент кода - структура фактического файла индекса немного отличается, новажные части есть).Я проверил индекс нескольких файлов CHM, но структуры тегов ul , li никогда не бывают одинаковыми.Статично только одно: есть теги param , которые содержат информацию о главе, разделе, любых заголовках и ссылках на их HTML

. Из-за этого я пытаюсь опираться только наинформация о глубине определенных тегов param для преобразования списка в структуру XML (главным образом в структуру DocBook - см. второй фрагмент кода).

<ul>
  <li>
    <param attr="value"/>
    <ul>
      <li>
        <param attr="value"/>
        <ul>
          <li>
            <param attr="value"/>
          </li>
        </ul>
      </li>
      <li>
        <param attr="value"/>
        <ul>
          <li>
            <param attr="value"/>
          </li>
          <li>
            <param attr="value"/>
          </li>
        </ul>
      </li>
      <li>
        <param attr="value"/>
        <ul>
          <li>
            <param attr="value"/>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

Мне удалось преобразовать некоторые индексы (аналогично предыдущему фрагменту кода) для структуры DocBook, но проблема в том, что моя таблица стилей XSL недостаточно универсальна.Если у кого-то есть идея преобразовать подобный список HTML в структуру DocBook, используя только информацию о глубине тегов param, пожалуйста, дайте мне несколько указателей.

Так, например, теги параметров с глубиной X будут преобразованы в элемент book , параметры с глубиной X + 1 будет преобразован в главу и так далее - конечно, всегда правильно вложенный.

<book>
  <title>value1</title>
  <chapter>
    <title>value2</title>
    <section>
      <title>value3</title>
    </section>
  </chapter>
  <chapter>
    <title>value4</title>
    <section>
      <title>value5</title>
    </section>
    <section>
      <title>value6</title>
    </section>
  </chapter>
  <chapter>
    <title>value7</title>
    <section>
      <title>value8</title>
    </section>
  </chapter>
</book>

1 Ответ

2 голосов
/ 29 августа 2010

Если ваша основная проблема заключается в том, как создать другой элемент в зависимости от глубины в дереве ввода, то следующая таблица стилей демонстрирует один из способов сделать это: во-первых, выяснить уровень вложенности с помощью count() элементов на ancestor-or-self ось , а затем с помощью xsl:element создать элемент с динамически определяемым именем.

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="li">
    <xsl:variable name="depth" select="count(ancestor-or-self::li)"/>
    <xsl:variable name="tag">
      <xsl:choose>
        <xsl:when test="$depth = 1">book</xsl:when>
        <xsl:when test="$depth = 2">chapter</xsl:when>
        <xsl:otherwise>section</xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:element name="{$tag}">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="param">
    <title>
      <xsl:value-of select="@attr"/>
    </title>
  </xsl:template>

</xsl:stylesheet>

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

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="li[count(ancestor-or-self::li) = 1]">
    <book>
      <xsl:apply-templates/>
    </book>
  </xsl:template>

  <xsl:template match="li[count(ancestor-or-self::li) = 2]">
    <chapter>
      <xsl:apply-templates/>
    </chapter>
  </xsl:template>

  <xsl:template match="li[count(ancestor-or-self::li) &gt; 2]">
    <section>
      <xsl:apply-templates/>
    </section>
  </xsl:template>

  <xsl:template match="param">
    <title>
      <xsl:value-of select="@attr"/>
    </title>
  </xsl:template>

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