2013-11-27 39 views
0

我正在將一些生成的DocBook xml(來自Doxygen)轉換爲我的公司xml,這實際上是DocBook的子集。有像下面這樣的para元素:xslt壓扁DocBook 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> 

由於我們的DocBook的子集不喜歡對位中塊元素,如桌子,或人物,我想解析這個元素,並把各地新para元素文本的那些作品,這樣我會有這樣的事情:

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

此前,以爲我再也看不到任何東西這個複雜的,我把表para元素之外是這樣的:

<xsl:when test="(child::figure | child::table) and (./text())"> 
    <Para> 
     <xsl:value-of select="./text()"/> 
    </Para> 
    <xsl:apply-templates select="*"/> 
</xsl:when> 

但是,這最終只捕捉到第一個文本節點,並搞砸了其他的東西。

任何人都可以建議,希望有一個優雅的方式來處理這個,如果para元素是這個混亂?

感謝,

拉斯

更新:我忘了自我介紹一個角落的情況。我編輯了上面的源代碼,查看鏈接元素。當前的解決方案從源中刪除包含的para元素。

回答

0

我不得不更正一些XML示例,以便它格式良好。但以下幾點:

<xsl:template match="para"> 
     <xsl:for-each select="node()"> 
      <xsl:choose> 
       <xsl:when test="self::text() and normalize-space(.)!=''"> 
        <xsl:element name="para"> 
         <xsl:apply-templates select="."/> 
        </xsl:element> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:apply-templates select="."/> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:for-each> 
    </xsl:template> 
    <xsl:template match="text()"> 
     <xsl:copy-of select="."/> 
    </xsl:template> 
    <xsl:template match="literallayout"> 
     <xsl:copy-of select="."/> 
    </xsl:template> 
    <xsl:template match="table"> 
     <xsl:copy-of select="."/> 
    </xsl:template> 

輸出:

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

我希望幫助。

+0

你可以改變的到的處理任何子元素,他們自己的模板? –

+0

是的。將編輯響應。 – kcstrong

+0

對不起,如果我是密集的,你是說Erlocks的答案,我可以改變來處理任何子元素,他們自己的模板? –

2

你可以把每一個文本節點para元素中變成自己para使用類似

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="@*|node()"> 
    <xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy> 
    </xsl:template> 

    <xsl:template match="para"> 
    <xsl:apply-templates /> 
    </xsl:template> 

    <xsl:template match="para/text()"> 
    <para><xsl:value-of select="." /></para> 
    </xsl:template> 
</xsl:stylesheet> 

,但是這未必是足夠的,如果你只是想在一定子元素,打破了對與不是別人。

0

我應該使用這些模板:

<xsl:template match="para"> 
    <xsl:apply-templates select="node()" mode="flat" /> 
</xsl:template> 

<xsl:template match="*" mode="flat"> 
    <xsl:copy-of select="." /> 
</xsl:template> 

<xsl:template match="text()[normalize-space()!='']" mode="flat"> 
    <para> 
     <xsl:value-of select="."/> 
    </para> 
</xsl:template> 

<xsl:template match="text()[normalize-space()='']" mode="flat" />