xsl: как смешать преобразование личности и пользовательские правила? - PullRequest
0 голосов
/ 26 апреля 2018

Я получил xml (каталог книг с обложками), для которого я создал xsl, который отображает книги, как если бы они были на книжных полках.

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

Как я могу это сделать? Я имею в виду, что я уже написал правило для "/" и потомков ("книги", "авторы"), если я добавлю правило идентификации, будет хорошо, пока оно не вызовет себя, но когда одно из моих пользовательских правил будет соответствовать, я начну вывести текст, связанный с пользовательским правилом.

EDIT

Как предложили Мартин Хоннен и Майкл Кей, решение было использовать режим.

<xsl:template match="/"> 
 <html> 
  <body> 
  ...
  <xsl:apply-templates select="foo"" /> 
  ...
  <textarea>
    <xsl:apply-templates select="//*"          mode="SERIALIZE" />
  </textarea>
  </body> 
 </html> 
</xsl:template>

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

Обратите внимание на режим = "SERIALIZE":
при вызове применять шаблоны,
в определении шаблона личности и
внутри него при рекурсивном вызове.

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Способ смешать два разных способа обработки одних и тех же узлов состоит в использовании режимов. Вы можете определить два разных режима обработки, прикрепив различные атрибуты mode к правилам шаблона, и вы можете начать обработку в определенном режиме, добавив атрибут mode к инструкции xsl:apply-templates.

0 голосов
/ 26 апреля 2018

Если вы хотите показать разметку входного узла, вам нужно ее сериализовать. В XSLT 3 с поддержкой XPath 3.1 вы можете сделать это с помощью функции serialize, например,

<code><xsl:template match="book" mode="show">
  <pre>
    <xsl:value-of select="serialize(.)"/>
  
</ XSL: шаблон>

https://xsltfiddle.liberty -development.net / jyH9rM4 / 1 содержит пример использования XSLT 3 и функции serialize для вывода разметки элемента ввода book внутри HTML pre Элемент результата.

В более ранних версиях XSLT вам необходимо проверить, поддерживает ли ваш процессор XSLT функцию расширения или вам нужно использовать XSLT для сериализации узла, поэтому я бы предложил использовать существующие библиотеки, такие как http://lenzconsulting.com/xml-to-string/xml-to-string.xsl, документированные. в http://lenzconsulting.com/xml-to-string/,, так как делать это правильно с пространствами имен и экранировать - сложная задача, такая библиотека делает лучше, чем быстрые попытки написать шаблон для элементов и узлов атрибутов для получения некоторых тегов.

С другой стороны, если вы действительно хотите использовать текстовую область HTML, учитывая, что ее модель содержимого представляет собой текст, вы можете получить способ вывода элемента внутри элемента textara, например. <textarea><xsl:copy-of select="."/></textarea> или, если вы предпочитаете, пройти через преобразование личности. Правильный инструмент с XSLT для разделения двух шаблонов для одного и того же совпадающего узла (узлов) - это использование именованного mode как минимум для одного шаблона. В XSLT 1.0 вам потребуется настроить шаблон преобразования идентификаторов также для этого режима, в XSLT 2 вы можете изменить шаблон преобразования идентификаторов, чтобы использовать mode="#all" для xsl:template и mode="#current" для xsl:apply-templates внутри.

https://xsltfiddle.liberty -development.net / gWmuiJ2 / 1 содержит пример, который просто копирует элемент book через содержимое HTML-элемента textarea с помощью <xsl:copy-of select="."/>, и браузеры, кажется, справляются с этим штрафом для отображения разметки XML.

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