2012-03-18 30 views
3

我試圖從XML文件中刪除節點。對每個XML只使用一個XSLT,我需要根據文檔元素的子元素數量在XSLT中做出決定。使用XSLT根據節點數量對條件進行XML轉換

<root> 
    <branch> 
    <foo>bar</foo> 
    </branch> 
<root> 

應轉變成

<branch> 
    </branch> 

<root> 
    <branch> 
    <foo>bar</foo> 
    </branch> 
    <branch> 
    <foo>baz</foo> 
<root> 

<root> 
    <branch> 
    </branch> 
    <branch> 
    </branch> 
<root> 

即,根元素應被刪除,如果其(唯一)子可以充當作爲新的文件根目錄o f應用XSLT後的結果XML。每個事件都必須刪除<foo>節點。

有沒有辦法用一個XSL執行這個操作?

回答

2

嘗試

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

<xsl:template match="root[*[2]]"> 
    <xsl:copy> 
    <xsl:apply-templates/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="root[* and not(*[2])]"> 
    <xsl:apply-templates/> 
</xsl:template> 

<xsl:template match="branch/foo"/> 
+0

+1謝謝,似乎在我的沙箱裏工作。我只是在學習XSLT:像[*和不...]這樣的正則表達式需要XSLT 2.0嗎? – msi 2012-03-18 14:05:02

+0

僅在XSLT和XPath 2.0中支持字符串匹配的正則表達式。然而,我只使用XSLT 1.0元素匹配模式作爲match =「root [* [2]]」'只是'match =「root [child :: * [2]]的簡寫形式''意思是匹配'root '具有至少兩個任何名字的子元素的元素。 – 2012-03-18 14:18:00

2

一種更簡單,更短和更通用的(無元素名稱硬編碼)溶液

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

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

<xsl:template match="/*[not(*[2])]"> 
    <xsl:apply-templates/> 
</xsl:template> 

<xsl:template match="/*/*/node()"/> 
</xsl:stylesheet> 

當該變換是在第一提供的XML文檔施加(糾正成良構):

<root> 
    <branch> 
     <foo>bar</foo> 
    </branch> 
</root> 

有用,正確的結果產生

<branch></branch> 

當相同的變換在第二提供的XML文檔(再次需要用於良好性將被校正)施加:

<root> 
    <branch> 
     <foo>bar</foo> 
    </branch> 
    <branch> 
     <foo>baz</foo> 
    </branch> 
</root> 

再次通緝,產生正確的輸出

<root> 
    <branch></branch> 
    <branch></branch> 
</root> 

說明

  1. identity rule副本的每個節點 「原樣」。

  2. 有兩個模板覆蓋特定節點的標識模板並以不同方式處理這些節點。

  3. 第一個覆蓋模板匹配沒有第二個元素子元素的頂層元素。它不會複製元素本身,而是處理其子元素。

  4. 第二個重寫模板匹配頂層元素的大子元素的任何元素。該模板沒有一個機構,這意味着所有這些匹配元素被忽略,且不包含在輸出(換句話說 - 「刪除」)

請注意

無論文檔中的元素名稱如何,此轉換都可以應用於任何 XML文檔,並且仍會生成所需的正確結果。

例如,當該XML文檔上施加:

<t> 
    <b> 
     <f>brrr</f> 
    </b> 
    <b> 
     <f>bzzz</f> 
    </b> 
</t> 

有用,正確的結果產生

<t> 
    <b></b> 
    <b></b> 
</t> 

對比度這由當前所產生的結果 - 接受的答案

<t> 
    <b> 
     <f>brrr</f> 
    </b> 
    <b> 
     <f>bzzz</f> 
    </b> 
</t>