2013-07-04 29 views
3

我正在将此半html,semi xml wiki翻译成DITA。我的最终目标是根据h标题实现嵌套。基本上移动body节点外的标题节点(例如h2)之后的节点,并用topic/body包装它们。标题水平可能会下降至h6XSLT:将标题标签的同义词移动到单独的主题中

我看到这个post解决了类似的问题,但我没有足够的知识来修改它来关闭其他嵌套元素之前的身体标记。

HTML/XML

<topic id="pageTitle"> 
    <title>Page Title</title> 
    <body> 
     <p>some contents.</p> 
     <h2>heading title</h2> 
     <p>some more content under h heading</p> 

     <h3>sub-heading title</h3> 
     <p>some more content under sub heading</p> 
     <p>some more content under sub heading</p> 

     <h2>heading title</h2> 
     <p>some more content under h heading</p> 
    </body> 
</topic> 

我想实现DITA筑巢

<topic id="pageTitle"> 
    <title>Page Title</title> 
    <body> 
     <p>some contents.</p> 
    </body> 

    <topic id="headingtitle"> 
     <title>heading title</title> 
     <body> 
     <p>some more content under h heading</p> 
     </body> 

     <topic id="sub-headingtitle"> 
     <title>sub-heading title</title> 
     <body> 
      <p>some more content under sub heading</p> 
      <p>some more content under sub heading</p> 
     </body> 
     </topic> 
    </topic> 

    <topic id="headingtitle"> 
     <title>heading title</title> 
     <body> 
     <p>some more content under h heading</p> 
     </body> 
    </topic> 
</topic> 

请注意:在<body>标签关闭其他的话题开始之前。这是DITA的标准,该主题不得嵌入到另一主题的内部。另外,如果身体节点紧跟着一个标题节点,那么身体节点将被移除。

例如,XML

<topic id="pageTitle"> 
    <title>Page Title</title> 
    <body> 
     <h2>heading title</h2> 
     <p>some more content under h heading</p> 
    </body> 
</topic> 

目标

<topic id="pageTitle"> 
    <title>Page Title</title> 

    <topic id="headingtitle"> 
     <title>h2 heading</title> 
     <body> 
     <p>some more content under h heading</p> 
     </body> 
    </topic> 

</topic> 

回答

4

这里是一个递归函数使用XSLT 2.0和for-each-groupgroup-starting-with我的建议:

<xsl:stylesheet 
    version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:mf="http://example.com/mf" 
    exclude-result-prefixes="xs mf"> 

<xsl:output indent="yes"/> 

<xsl:function name="mf:get-id-sub" as="xs:string"> 
    <xsl:param name="level" as="xs:integer"/> 
    <xsl:sequence select="string-join(for $i in 3 to $level return 'sub-', '')"/> 
</xsl:function> 

<xsl:function name="mf:group" as="element()*"> 
    <xsl:param name="elements" as="element()*"/> 
    <xsl:param name="level" as="xs:integer"/> 
    <xsl:for-each-group select="$elements" group-starting-with="*[local-name() eq concat('h', $level)]"> 
    <xsl:choose> 
     <xsl:when test="not(self::*[local-name() eq concat('h', $level)])"> 
     <body> 
      <xsl:apply-templates select="current-group()"/> 
     </body> 
     </xsl:when> 
     <xsl:otherwise> 
     <topic id="{mf:get-id-sub($level)}headingtitle"> 
      <xsl:apply-templates select="."/> 
      <xsl:sequence select="mf:group(current-group() except ., $level + 1)"/> 
     </topic> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:for-each-group> 
</xsl:function> 

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

<xsl:template match="topic[@id = 'pageTitle']/body"> 
    <xsl:sequence select="mf:group(*, 2)"/> 
</xsl:template> 

<xsl:template match="h2 | h3 | h4 | h5 | h6"> 
    <title> 
    <xsl:apply-templates/> 
    </title> 
</xsl:template> 

</xsl:stylesheet> 

它把

<topic id="pageTitle"> 
    <title>Page Title</title> 
    <body> 
     <h2>heading title</h2> 
     <p>some more content under h heading</p> 
    </body> 
</topic> 

<topic id="pageTitle"> 
    <title>Page Title</title> 
    <topic id="headingtitle"> 
     <title>heading title</title> 
     <body> 
     <p>some more content under h heading</p> 
     </body> 
    </topic> 
</topic> 

<topic id="pageTitle"> 
    <title>Page Title</title> 
    <body> 
     <p>some contents.</p> 
     <h2>heading title</h2> 
     <p>some more content under h heading</p> 

     <h3>sub-heading title</h3> 
     <p>some more content under sub heading</p> 
     <p>some more content under sub heading</p> 

     <h2>heading title</h2> 
     <p>some more content under h heading</p> 
    </body> 
</topic> 

<topic id="pageTitle"> 
    <title>Page Title</title> 
    <body> 
     <p>some contents.</p> 
    </body> 
    <topic id="headingtitle"> 
     <title>heading title</title> 
     <body> 
     <p>some more content under h heading</p> 
     </body> 
     <topic id="sub-headingtitle"> 
     <title>sub-heading title</title> 
     <body> 
      <p>some more content under sub heading</p> 
      <p>some more content under sub heading</p> 
     </body> 
     </topic> 
    </topic> 
    <topic id="headingtitle"> 
     <title>heading title</title> 
     <body> 
     <p>some more content under h heading</p> 
     </body> 
    </topic> 
</topic>