2013-12-06 3 views
1

Многие из вас помочь мне в этом предыдущий вопрос: xslt flattening out child elements in a DocBook para elementуплощение и XSLT unflattening DocBook пункт элемент

Был дополнительный поворот к этой проблеме, что я хотел увидеть, если кто-то делал это раньше. Вспоминая образец текста раньше. На предыдущий вопрос был дан ответ, в котором был рассмотрен вопрос об использовании текста между элементами блока и обертывании их с помощью элемента para, так как наша схема не любит блокировать элементы, такие как tabe, figure и т. Д. В элементе para.

<para>some text..... 
    <literallayout> 
    </literallayout> 
more text.... 
<table> 
    ... 
</table> 
even more text 
<table>...</table> 
<literallayout>text also look here</literlayout> 
more text <link xlink:href="http://someurl.com"> 
</para> 

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

<para>more text <link xlink:hred="http://someurl.com">someurl</link></para> 

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

Я могу придумать, как это сделать, хотя и взломанным способом, на любом другом языке программирования, но вам нужна помощь от гуру XSLT, чтобы рассказать мне об элегантном способе сделать это!

Был запрос на получение дополнительной информации. В приведенном выше примере я должен иметь возможность выводить следующее:

<para>some text..... </para> 
<literallayout> 
</literallayout> 
<para> more text.... </para> 
<table> ... </table> 
<para> even more text </para> 
<table>...</table> 
<literallayout> 
<para>more text <link xlink:hred="http://someurl.com">someurl</link></para> 

Надеюсь, это упростит ситуацию.

Спасибо всем за вашу помощь.

Russ

+0

Можете ли вы пояснить это? В вашем примере элемент 'link' уже находится в элементе' para', а именно тот, который запускает примерный документ. –

+0

Конечно, позвольте мне немного обновить пример. –

ответ

1

Это классическая проблема. Насколько мне известно, сглаживание обычно решается с помощью XSLT-группировки. Конечно же, с XSLT 1 это нелегко, когда вам нужно использовать алгоритмы на основе рекурсии для его реализации. Но давайте рассмотрим более простое решение (XSLT 2):

<xsl:stylesheet version="2.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema" 
       xmlns:f="http://stackoverflow.com/xslt-functions" 
       xmlns:doc="http://docbook.org/ns/docbook" 
       xmlns="http://docbook.org/ns/docbook" 
       exclude-result-prefixes="#all"> 


    <xsl:variable name="block-elements" select="QName('http://docbook.org/ns/docbook', 'table'), 
               QName('http://docbook.org/ns/docbook', 'figure')"/> 


    <xsl:template match="doc:para"> 
     <xsl:for-each-group select="node()" group-adjacent="f:is-block-level-element(.)"> 
      <xsl:choose> 
       <!-- If current node is a block element process the node as is --> 
       <xsl:when test="current-grouping-key()"> 
        <xsl:apply-templates select="current-group()"/> 
       </xsl:when> 
       <!-- Otherwise, wrap it in para element --> 
       <xsl:otherwise> 
        <para> 
         <xsl:apply-templates select="current-group()"/> 
        </para> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:for-each-group> 
    </xsl:template> 


    <xsl:function name="f:is-block-level-element" as="xs:boolean"> 
     <xsl:param name="node" as="node()"/> 

     <xsl:sequence select="$node instance of element() and 
           node-name($node) = $block-elements"/> 
    </xsl:function> 

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

</xsl:stylesheet> 

Содержание назначения будет:

<section xmlns="http://docbook.org/ns/docbook"> 
    <para>some text..... 
     <literallayout> 
     </literallayout> 
     more text.... 
    </para> 
    <table> 
     ... 
    </table> 
    <para> 
     even more text 
    </para> 
    <table>...</table> 
    <para> 
     <literallayout>text also look here</literallayout> 
     more text 
     <link/> 
    </para> 
</section> 
+0

Мне нужно обернуть голову вокруг, но это выглядит хорошо! –

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