我有这个xml:
<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 :(得分:0)
如果,我使用您的评论作为您的目标:&#34;我希望得到所有非空元素,而不是一两个。所以我们离开了树和四个&#34;,你需要修复你的Xpath来实现它。 &#34; [否(节点())]&#34;将node()排除在每个node()作为子节点,但node()也选择文本节点,这就是为什么你什么也得不到。如果您只想过滤掉元素为子元素的元素,请使用&#39; &#39;。 因此,Row的这个模板应该完成工作(未测试):
<xsl:template match="Row">
<xsl:apply-templates select="*[not(self::one or self::two) and not(* or text() ='')] "/>
</xsl:template>
答案 1 :(得分: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>
答案 2 :(得分:0)
我得到的代码最终有效:
<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>