2013-10-22 40 views
0

我需要將混合的「標籤和文本」XML拆分爲兩個「純」部分:一部分僅包含數據標籤(任何標籤不是<b>或或<sup>格式標籤); o其他部分只有「僅文本」(//text()和格式標籤)。如何使用XSLT-1將格式化文本中的標籤分開?

輸入例:

<root> 
    Nonono <i>nonon</i> <data1/> <b>nono</b> 
    <data2>nononono <i>no</i>nononon</data2>. 
    <data3>blablabla<data4/></data3> 
    </root> 

輸出例如:

<root> 
    <myTags> 
     <data1/> 
     <data2>nononono <i>no</i>nononon</data2> 
     <data3>blablabla<data4/></data3> 
    </myTags> 

    <myText> 
     Nonono <i>nonon</i> <b>nono</b> 
     nononono <i>no</i>nononon . blablabla 
    </myText> 
    </root> 

編輯具有一個輸入是更現實的,

Nonono <i>nonon</i> <data1/> <b>nono <data66/> </b> 

必須輸出

 <data1/><data66/> 

這種情況下表達一個問題更復雜一點。它可以發生在任何級別。


下面的xsl:transform核心我的XSLT的(即不是出於行爲!),

<xsl:template match="/"> 
    <root> 
    <myTags><xsl:call-template name="copyOnlyTags"/></myTags> 
    <myText><xsl:call-template name="copyOnlyTextAndFormat"/></myText> 
    </root> 
</xsl:template> 

<!-- LIB --> 

<xsl:template name="copyOnlyTags"> 
    <xsl:copy> 
     <xsl:copy-of select="@*"/> 
     <xsl:for-each select="node()[not(self::text())]"> 
     <xsl:choose> 
      <xsl:when test="count(*)=0"> <!-- terminal --> 
      <xsl:copy-of select="."/> 
      </xsl:when> 
      <xsl:otherwise>  <!-- recurrence --> 
      <xsl:call-template name="copyOnlyTags"/> 
      </xsl:otherwise> 
     </xsl:choose> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 

<xsl:template name="copyOnlyTextAndFormat"> 
     <xsl:for-each select="node()"> 
     <xsl:choose> 
      <xsl:when test="self::text()"> 
      <xsl:value-of select="."/> 
      </xsl:when> 
      <xsl:when test="name()='i' or name()='sup' or name()='sub' or name()='b'"> 
      <xsl:copy-of select="."/><!-- suppose only text into --> 
      </xsl:when> 
      <xsl:otherwise>  <!-- recurrence --> 
      <xsl:call-template name="copyOnlyTextAndFormat"/> 
      </xsl:otherwise> 
     </xsl:choose> 
     </xsl:for-each> 
</xsl:template> 

回答

1

XSLT是不是要告訴你想讓它做什麼處理器,它是關於陳述導致你想要什麼具有。

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

    <xsl:template match="root"> 
    <xsl:copy> 
     <myTags> 
     <xsl:apply-templates select="node()" mode="data" /> 
     </myTags> 
     <myText> 
     <xsl:apply-templates select="node()" mode="format" /> 
     </myText> 
    </xsl:copy> 
    </xsl:template> 

    <!-- unless stated otherwise, we want no output --> 
    <xsl:template match="node()" mode="data" /> 
    <xsl:template match="node()" mode="format" /> 

    <!-- DATA MODE: data elements should be copied --> 
    <xsl:template match="*[starts-with(name(), 'data')]" mode="data"> 
    <xsl:copy-of select="." /> 
    </xsl:template> 

    <!-- DATA MODE: format elements should be passed silently --> 
    <xsl:template match="*[not(starts-with(name(), 'data'))]" mode="data"> 
    <xsl:apply-templates select="node()" mode="data" /> 
    </xsl:template> 

    <!-- FORMAT MODE: format elements and text nodes should be copied --> 
    <xsl:template match="text() | *[not(starts-with(name(), 'data'))]" mode="format"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()" mode="format" /> 
    </xsl:copy> 
    </xsl:template> 

    <!-- FORMAT MODE: data elements should be passed silently --> 
    <xsl:template match="*[starts-with(name(), 'data')]" mode="format"> 
    <xsl:apply-templates select="node()" mode="format" /> 
    </xsl:template> 

</xsl:stylesheet> 

對於

<root> 
    Nonono <i>nonon</i> <data1/> <b>nono</b> 
    <data2>nononono <i>no</i>nononon</data2>. 
    <data3>blablabla<data4/></data3> 
</root> 

輸出是

<root> 
    <myTags> 
    <data1/> 
    <data2>nononono <i>no</i>nononon</data2> 
    <data3>blablabla<data4/></data3> 
    </myTags> 
    <myText> 
    Nonono <i>nonon</i> <b>nono</b> 
    nononono <i>no</i>nononon. 
    blablabla 
    </myText> 
</root> 

<root> 
    Nonono <i>nonon</i> <data1/> <b>nono <data66/> </b> 
</root> 

它產生

<root> 
    <myTags> 
    <data1/> 
    <data66/> 
    </myTags> 
    <myText> 
    Nonono <i>nonon</i> <b>nono </b> 
    </myText> 
</root> 
+0

嗡嗡聲,我有'copy-of'的問題,因爲破壞順序(我需要保留順序);並且我需要身份轉換,因爲data1,data2僅僅是示例,可以是「任何其他事物」(data4,data5,x,y,...任何其他不是格式化的標籤)。 –

+0

*「任何其他事物」*可能是'*'或'node()'或'* [not(self:i或self :: b)]',這取決於您的轉換設置的其餘部分。 – Tomalak

+0

是的,'* [not(self:i or self :: b)]'是「rest」... Ops,檢查myText的編輯輸出,與你的不一樣。 –

相關問題