2016-12-11 6 views
1

Я пытаюсь изменить некоторый код XSLT dblatex, который обрабатывает документы docbook в LaTeX. Мы сделали немало модов для наших местных потребностей, но у меня есть я в тупике.wrap на основе атрибута

Существует атрибут «аудитория», который может отображаться практически на любом элементе XML docbook. В наших документах большинство элементов не отмечены для этого attr, но некоторые из них отмечены как «tech», так и «nontech», например.

<chapter audience='tech'> 
    (lot of stuff) 
</chapter> 

Вместо того чтобы использовать механизм «профилирование», я хотел бы, чтобы обернуть код LaTeX, которая является результатом обработки элементов, которые имеют такой атрибут, с LaTeX тега, т.е.

\technical{ \chapter (lots of stuff) } 

Мои попытка XSLT кода для выполнения этой упаковки выглядит следующим образом:

<xsl:template match=".[@audience='tech']"> 
    <xsl:text>\technical{</xsl:text> 
    <xsl:apply-templates/> 
    <xsl:text>}</xsl:text> 
</xsl:template> 

к сожалению, результат этого является то, что XML-элемент, который соответствует этому шаблону не обрабатывается, только его дочери (как и следовало ожидать, когда в коде xslt нет атрибута @select). Так что, если оригинал был

<chapter role='tech'> 
    <section>blah blah</section> 
</chapter> 

то выходной LaTeX имеет код LaTeX для раздела, но не для этой главы.

Наоборот, если изменить код выше XSLT, так что имеет явное

<xsl:apply-templates select="."/> 

тогда я получаю бесконечную рекурсию.

Понятно, что я хочу сказать xslt обработать элемент XML с атрибутом @audience attr, выведя оболочку LaTeX \ technical {...}, затем обработать тот же элемент, игнорируя @ аудиторию = атрибут «tech».

Есть ли способ сделать это? Я использую xslt v1 в другом месте, хотя я думаю, что если нужно использовать xslt v2, я мог бы внести изменения (не знаю, как это делается, но должно быть способ ...)

ответ

0

Вы можете использовать mode атрибут, доступный с XSLT 1.0. Режимы позволяют различать шаблоны, соответствующие тем же узлам, но выполнять разные действия. Следовательно, одни и те же элементы можно обрабатывать несколько раз. Более подробную информацию можно найти in the standard.

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

    <xsl:template match="/"> 
     <xsl:apply-templates select="*" mode="firstRun"/> 
    </xsl:template> 

    <xsl:template match="chapter[@audience='tech']" mode="firstRun"> 
     <xsl:text>\technical{</xsl:text> 
      <xsl:apply-templates select="." mode="secondRun"/> 
     <xsl:text>}</xsl:text> 
    </xsl:template> 

    <xsl:template match="chapter" mode="secondRun"> 
     <xsl:text>\chapter{</xsl:text> 
      <xsl:value-of select="."/> 
     <xsl:text>}</xsl:text> 
    </xsl:template> 

</xsl:stylesheet> 
+0

Будет ли это требовать от меня указать режим на всех элементах, разрешенных схемой, чтобы иметь значение @audience attr? Который я, конечно, не хотел бы делать (в docbook есть 100 элементов, а код dblatex уже достаточно сложный). Полагаю, мне нужно попробовать и посмотреть, могу ли я опустить «secondRun» выше. –

+0

Вы можете опустить режим «secondRun», я включил его только для иллюстрации механизма. В общем случае, если элемент 'xsl: apply-templates' задает режим, тогда он применяет только шаблоны этого режима. В противном случае применяются шаблоны, которые не относятся к какому-либо режиму (т. Е. Поведение по умолчанию). И наоборот, шаблон, определяющий режим, может быть согласован только с помощью шаблона 'xsl: apply-templates' того же режима. – Meyer

+0

@ Майк Максвелл, был ли этот ответ достаточным или вам нужна дальнейшая помощь? – Meyer

Смежные вопросы