Использование XSLT для рекурсивного объединения файла XHTML в один файл XHTML - PullRequest
4 голосов
/ 26 июня 2011

Я пытаюсь создать таблицу стилей XSL, которая позволяет объединять файлы XHTML, которые ссылаются из другого файла XHTML.В свою очередь, любые файлы XHTML, указанные из указанных файлов, также должны быть объединены, и так далее.Таким образом, должна быть возможность рекурсивного объединения всего XHTML, на который прямо или косвенно ссылается начальный файл XHTML, в один файл XHTML.Ссылки являются строго иерархическими.

Пример:

Файл a.html:

<html>
    <body>Text1<br/><a href="b.html">Link</a></body>
</html>

Файл b.html:

<html>
    <body>Text2<br/><a href="c.html">Link</a></body>
</html>

Файл c.html:

<html>
    <body>Text3<br/></body>
</html>

Полученный объединенный файл при запуске с a.html:

<html>
    <body>Text1<br/>Text2<br/>Text3<br/></body>
</html>

Я не знаю точно, как решить эту проблему с XSLT.Любая помощь приветствуется.

Ответы [ 3 ]

3 голосов
/ 26 июня 2011

Как сказала Мерлин Морган-Грэм, ключом является функция document().Хотя это не сложно ...

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

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:template match="a">
    <xsl:apply-templates select="document(@href)/html/body/node()"/>
  </xsl:template>

</xsl:stylesheet>

с вашими 3 html-файлами и использованием a.html в качестве входных данных приводит к выводу:

<html>
  <body>Text1<br/>Text2<br/>Text3<br/>
  </body>
</html>

Кроме того, что действительно делает это возможным, это преобразование идентичности.Он передает все, что не соответствует другому шаблону, без изменений.

0 голосов
/ 26 июня 2011

Это преобразование :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" omit-xml-declaration="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="a">
  <xsl:apply-templates select=
  "document(@href)/*/body/node()"/>
 </xsl:template>
</xsl:stylesheet>

при применении к файлу "a.html":

<html>
    <body>Text1<br/><a href="b.html">Link</a></body>
</html>

дает желаемый, правильный результат :

<html><body>Text1<br/>Text2<br/>Text3<br/></body></html>

Объяснение

  1. Правило идентификации копирует каждый узел "как есть".

  2. Единственный переопределяющий шаблон соответствует любому элементу a.

  3. В этом шаблоне начинается обработка документа, указанного в атрибуте href элемента a. Важно, чтобы мы использовали стандартную функцию XSLT document().

0 голосов
/ 26 июня 2011

Возможно, это будет немного сложнее, но посмотрите на функцию document().

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

Если не получится, что document() позволит вам преобразовать преобразование в другие документы, вы можете вызвать преобразование в цикле и записать преобразование для повторного вызова. Тогда вам понадобится какой-нибудь способ проверить, когда можно прекратить преобразование.

Один из способов узнать, когда вам следует остановиться, - это провести различие между исходными и целевыми документами.

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

Но, возможно, есть способ продолжить преобразование с помощью вложенных поддокументов.

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