2014-11-03 59 views
0

我有這樣的XML:XSL組不是空的元素

<Row> 

<one>1</one> 
<two>2</two> 
<tree>3</tree> 
<four>4</four> 
<five></five> 
<six></six> 
<seven></seven> 

</Row> 

預期的XML:

<tree>3</tree> 
<four>4</four> 

我想忽略我的條件的所有元素和組。

我的XSL是:

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

    <xsl:template match="Row"> 
      <xsl:apply-templates select="*[not(self::one or self::two)] and *[not(node())] "/> 
    </xsl:template> 

但我得到一個空的XML。

+0

這是怎麼分組非空元素?元素'one'和'two'也包含文本,但不會出現在您的預期輸出中。 – 2014-11-03 07:31:25

+0

我想獲得所有不是空的元素,而不是一個和兩個。所以我們留下了樹和四個 – lshaked 2014-11-03 07:49:28

回答

0

如果我使用你的評論作爲你的目標:「我想得到所有不是空的元素,而不是一兩個,所以我們留下了樹和四個」,你需要修復你的Xpath來實現它。 「[not(node())]」將會排除每個節點(),但節點()會選擇文本節點,這就是爲什麼你什麼都得不到的原因。如果只想過濾元素爲子元素,請使用''。 所以,這個模板的行應該做的工作(未測試):

<xsl:template match="Row"> 
     <xsl:apply-templates select="*[not(self::one or self::two) and not(* or text() ='')] "/> 
</xsl:template> 
0

什麼這條線從原來的代碼(我稍微改變了它,因爲你不能有]出現在謂詞的中間):

<xsl:apply-templates select="*[not(self::one or self::two) and not(node())] "/> 

做的是,用簡單的英語:

應用模板的元素,但只有當他們沒有one元素,或者如果他們不是two元素,並且僅當它們不包含任何子節點時。

但是,當然,您希望選擇完全相反的元素,即包含文本的元素。

在我看來,使用不同的模板來完成這個任務將是一個更乾淨的解決方案。

樣式

<?xml version="1.0"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:strip-space elements="*"/> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 

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

    <!--Traverse the Row element--> 
    <xsl:template match="Row"> 
     <xsl:apply-templates /> 
    </xsl:template> 

    <!--Do not apply templates to one, two or empty elements--> 
    <xsl:template match="Row/*[self::one or self::two or not(text())]"/> 

</xsl:stylesheet> 

XML輸出

注意,你是不是輸出格式良好的XML文檔。但這將是一個有效的XML 片段

<tree>3</tree> 
<four>4</four> 
0

我的作品finaly代碼:

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

    <xsl:template match="Row"> 
      <xsl:apply-templates select="*[not(normalize-space()='') and not (self::one or self::two)] "/> 
    </xsl:template> 

通知,not(normalize-space()='')應該在邏輯句子的開頭。

這將導致:

<tree>3</tree> 
<four>4</four> 
+0

不,覆蓋文本內容的條件是否最後沒關係。 - 不,你的代碼無效,因爲有兩個關閉']'。 – 2014-11-03 08:43:29

+0

表示無效評論。修復。 – lshaked 2014-11-03 08:47:48

+0

您可以嘗試「* [不(self :: one或self :: two)]而不是(normalize-space()='')」將句子的末尾不空,您將得到一個空文檔。 – lshaked 2014-11-03 08:48:29