Использование XSLT 1.0 для структурирования иерархического содержания (с различной глубиной) - PullRequest
0 голосов
/ 31 августа 2018

У меня есть различные книги в виде xml-файлов, которые содержат вложенные элементы div, содержащие заголовок записи и информацию об идентификаторе записи на разных уровнях - раздел / главы / записи статьи / стихи и т. Д.

Мне нужно вывести структуру оглавления, состоящую из разделов, объединяющих информацию заголовка дочернего элемента div для каждого элемента div в исходной структуре. Однако, если какой-либо из этих дочерних элементов div имеет свои собственные (grand-) дочерние элементы div, они требуют заполнения нового элемента section в выходных данных.


Осложнения таковы:
1) каждый элемент (т. е. div / title) должен отображаться в исходном порядке чтения (порядок, в котором они отображаются в xml, не имеет отношения к уровню div)
2) элементы могут появляться только один раз (т. е. информация div, используемая в заголовке, также не может быть включена как дочерний элемент другого раздела)
3) каждая книга может иметь различную глубину вложенных элементов div (максимум 8 уровней)

Элемент header в выходных данных не требуется, если родительский заголовок использовался в качестве заголовка в предыдущем элементе section. Разделы могут быть бездетными.

Сильно упрощенная версия входного XML будет выглядеть так:

<div0>
  <div1>
    <title>Intro</title><id>A1</id>
  </div1>
  <div1>
    <title>Volume</title><id>A2</id>
    <div2>
      <title>Preface</title><id>A3</id>
    </div2>
    <div2>
      <title>Dedication</title><id>A4</id>
    </div2>
    <div2>
      <title>Part 1</title><id>A5</id>
      <div3>
          <title>Chapter 1</title><id>A6</id>
      </div3>
      <div3>
          <title>Chapter 2</title><id>A7</id>
      </div3>
      <div3>
          <title>Chapter 3</title><id>A8</id>
      </div3>
      <div3>
          <title>Chapter 4</title><id>A9</id>
          <div4>
            <title>Poem 1</title><id>A10</id>
          </div4>
          <div4>
            <title>Poem 2</title><id>A11</id>
          </div4>
      </div3>
      <div3>
          <title>Chapter 5</title><id>A12</id>
      </div3>
      <div3>
          <title>Chapter 6</title><id>A13</id>
      </div3>       
    </div2>
    <div2>
       <title>Part 2</title><id>A14</id>
      <div3>
          <title>Chapter 7</title><id>A15</id>
      </div3>
      <div3>
          <title>Chapter 8</title><id>A16</id>
          <div4>
            <title>Illustration 1</title><id>A17</id>
          </div4>
          <div4>
            <title>Illustration 2</title><id>A18</id>
          </div4>
          <div4>
            <title>Illustration 3</title><id>A19</id>
          </div4>
      </div3>
      <div3>
          <title>Chapter 9</title><id>A20</id>
      </div3>
      <div3>
          <title>Chapter 10</title><id>A21</id>
      </div3>
    </div2>
    <div2>
       <title>Back Matter</title><id>A22</id>
    </div2>
  </div1>
</div0>

Вывод, который я надеюсь получить:

<toc>
<section id="1">
  <level>1</level>
  <order>1</order>
  <header>Intro</header>
  <link>A1</link>
</section>

<section id="2">
  <level>1</level>
  <order>2</order>
  <header>Volume</header>
  <link>A2</link>
  <child>
    <name>Preface</name>
    <link>A3</link>
  </child>
  <child>
      <name>Dedication</name>
      <link>A4</link>
  </child>
</section>

<section id="3">
  <level>2</level>
  <parentSectionID>2</parentSectionID>
  <order>3</order>
  <header>Part 1</header>
  <link>A5</link>
  <child>
    <name>Chapter 1</name>
    <link>A6</link>
  </child>
  <child>
      <name>Chapter 2</name>
      <link>A7</link>
  </child>
  <child>
      <name>Chapter 3</name>
      <link>A8</link>
  </child>  
</section>

<section id="4">
  <level>3</level>
  <parentSectionID>3</parentSectionID>
  <order>4</order>
  <header>Chapter 4</header>
  <link>A9</link>
  <child>
    <name>Poem 1</name>
    <link>A10</link>
  </child>
  <child>
      <name>Poem 2</name>
      <link>A11</link>
  </child>
</section>

<section id="5">
  <level>2</level>
  <parentSectionID>3</parentSectionID>
  <order>5</order>
  <child>
    <name>Chapter 5</name>
    <link>A12</link>
  </child>
  <child>
      <name>Chapter 6</name>
      <link>A13</link>
  </child>
</section>

<section id="6">
  <level>2</level>
  <parentSectionID>2</parentSectionID>
  <order>6</order>
  <header>Part 2</header>
  <link>A14</link>
  <child>
    <name>Chapter 7</name>
    <link>A15</link>
  </child>
</section>

<section id="7">
  <level>3</level>
  <parentSectionID>6</parentSectionID>
  <order>7</order>
  <header>Chapter 8</header>
  <link>A16</link>
  <child>
    <name>Illustration 1</name>
    <link>A17</link>
  </child>
  <child>
    <name>Illustration 2</name>
    <link>A18</link>
  </child>
  <child>
    <name>Illustration 3</name>
    <link>A19</link>
  </child>
</section>

<section id="8">
  <level>2</level>
  <parentSectionID>2</parentSectionID>
  <order>8</order>
  <child>
    <name>Chapter 9</name>
    <link>A20</link>
  </child>
  <child>
      <name>Chapter 10</name>
      <link>A21</link>
  </child>
</section>

<section id="9">
  <level>2</level>
  <parentSectionID>2</parentSectionID>
  <order>9</order>
  <header>Back Matter</header>
  <link>A22</link>
</section>
</toc>

Я дошел до того, как определить, как найти все уровни div (используя старты с (local-name (), 'div') и проверил каждый на наличие дочерних элементов div и внуков div, но я не могу понять, как группировать их в разделы, которые разбиваются на новые разделы, когда обнаруживается, что у дочернего элемента div есть собственный дочерний элемент div, а затем возвращаются на предыдущий уровень для следующего дочернего элемента div без элемента div для внука. Либо я теряю порядок чтения в цикле for-each иначе я получаю дублирование в выводе.

Если кто-то может помочь с решением для группировки заголовков по разделам, при условии, что я понимаю методологию, я смогу разобраться, как заполнять идентификаторы разделов, информацию об уровне и т. Д.

...