2012-10-19 60 views
0

我有一個XML文件,該文件是一樣的東西:XSLT - 如何刪除標籤並保留內容?

<doc> 
    <element> 
    <word> 
     <text>one word</text> 
    </word> 
    <word> 
     <text>two words</text> 
    </word> 
    </element> 
    <element> 
    <other> 
     <text>the sky</text> 
    </other> 
    <word> 
     <text>NN NN</text> 
    </word> 
    </element> 
</doc> 

而且我想,當有對前一後兩個,像那樣只有一個標籤和線條的內容:

<element> 
    <word> 
     <text>one word</text> 
     <text>two words</text> 
    </word> 
</element> 

問題是我正在生成<xsl:element>以獲取<word>標記。此<xsl:element>已在<xsl:for-each>循環中,該循環將<word>標記按正確的順序排列(對屬性進行過濾)。

我以前的XML文檔是這樣的:

<doc> 
    <element class="word"> 
    <text>one word</text> 
    </element> 
    <element class="word"> 
    <text>NN NN</text> 
    </element> 
    <element class="word"> 
    <text>two words</text> 
    </element> 
    <element class="other"> 
    <text>the sky</text> 
    </element> 
</doc> 

任何幫助將是巨大的,謝謝:)

- 更多細節 -

這是我想要的結果有:

<doc> 
    <element> 
     <word> 
     <text>one word</text> 
     <text>two words</text> 
     </word> 
    </element> 
    <element> 
     <other> 
     <text>the sky</text> 
     </other> 
     <word> 
     <text>NN NN</text> 
     </word> 
    </element> 
</doc> 

而且我不能指定標籤單詞其他因爲我沒有一個封閉的標籤列表。所以我使用的xsl:變量

<xsl:for-each select="element"> 
    <xsl:variable name="name"> 
     <xsl:value-of select="@class"/> 
    </xsl:variable> 
    <xsl:element name="{$name}"> 
     <text> 
      <xsl:value-of select="."/> 
     </text> 
    </xsl:element> 
</xsl:for-each> 

回答

1

試試這個:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="element/*"> 
    <xsl:if test="not(preceding-sibling::*[name() = name(current())])"> 
     <xsl:copy> 
     <xsl:apply-templates select="* | following-sibling::*[name()=name(current())]/*" /> 
     </xsl:copy> 
    </xsl:if> 
    </xsl:template> 

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

它只是尋找那些沒有前一個兄弟與中element子節點同名(即每一個的第一個),然後將模板應用到它自己的子節點和任何後面的具有相同名稱的兄弟節點的子節點。

+0

感謝:它完美的作品:) – user1759737

0

您可以只使用<xsl:apply-templates/> 「解包」 的元素...

XML輸入

<doc> 
    <element> 
     <word> 
      <text>one word</text> 
     </word> 
     <word> 
      <text>two words</text> 
     </word> 
    </element> 
    <element> 
     <other> 
      <text>the sky</text> 
     </other> 
     <word> 
      <text>NN NN</text> 
     </word> 
    </element> 
</doc> 

XSLT 1.0

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

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

    <xsl:template match="element"> 
     <xsl:copy> 
      <word> 
       <xsl:apply-templates/> 
      </word> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="word|other"> 
     <xsl:apply-templates/> 
    </xsl:template> 

</xsl:stylesheet> 

輸出

<doc> 
    <element> 
     <word> 
     <text>one word</text> 
     <text>two words</text> 
     </word> 
    </element> 
    <element> 
     <word> 
     <text>the sky</text> 
     <text>NN NN</text> 
     </word> 
    </element> 
</doc> 
+0

非常感謝您的回答!這是我想要做的,但我的問題是我無法在匹配屬性中指定標籤的名稱,因爲我使用獲取了標籤的名稱。 – user1759737

0

該轉化

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="element/*"/> 
<xsl:template match="element/*[1]"> 
    <word> 
     <xsl:apply-templates select="../*/*"/> 
    </word> 
</xsl:template> 
</xsl:stylesheet> 

當所提供的XML文檔施加:

<doc> 
    <element> 
     <word> 
      <text>one word</text> 
     </word> 
     <word> 
      <text>two words</text> 
     </word> 
    </element> 
    <element> 
     <other> 
      <text>the sky</text> 
     </other> 
     <word> 
      <text>NN NN</text> 
     </word> 
    </element> 
</doc> 

產生(我猜是)通緝,正確的結果

<doc> 
    <element> 
     <word> 
     <text>one word</text> 
     <text>two words</text> 
     </word> 
    </element> 
    <element> 
     <word> 
     <text>the sky</text> 
     <text>NN NN</text> 
     </word> 
    </element> 
</doc> 
+0

謝謝Dimitre的幫助!這個結果幾乎是我想要的結果,但如果標籤不一樣,我不會應用規則。在這個例子中,結果可能不會改變第二個部分。但我一直在尋找:)謝謝你的快速回答。 – user1759737

+0

@ user1759737,對不起,您的評論無法理解。你是什​​麼意思?「」如果標籤不一樣,我不適用這個規則「你是什麼意思?」結果可能會改變第二個部分?「 –

+0

我在帖子中提供了更多細節,I希望這可以回答你的問題,謝謝你的幫助 – user1759737

相關問題