2014-11-03 32 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