2008-10-01 69 views
4

我有一些XML重复的元素,例如目的,它看起来像这样:检查在输出

<root> 
    <field1>test</field1> 
    <f2>t2</f2> 
    <f2>t3</f2> 
</root> 

我想用XSLT转换它,但我想抑制第二F2元素在输出中 - 我如何检查模板内部,以查看源代码中第二个f2元素的处理过程中f2元素是否已经存在于输出中?我的XSLT看起来是这样的,目前:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="no" omit-xml-declaration="yes" standalone="no" /> 
    <xsl:template match="/"> 
    <xsl:for-each select="./root"> 
     <output> 
     <xsl:apply-templates />   
     </output> 
    </xsl:for-each> 
    </xsl:template> 
    <xsl:template match="*" > 
     <xsl:element name="{name(.)}"> 
     <xsl:value-of select="." /> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

我需要做某种围绕XSL检查:元素在模板我想,但我不知道如何来询问输出文件,看是否该元素已经存在。

编辑:忘了pre标签,代码应该现在可见!

回答

7

这取决于您想要的系统范围。

即你只关心的是同父的子女,或在同一级别的所有元素(“堂兄弟”,如果你喜欢),或在文档中的任意元素的元素...

在第一您可以检查前面的兄弟轴来查看是否存在其他具有相同名称的元素。

<xsl:if test="count(preceding-sibling::node()[name()=name(current())])=0"> 
    ... do stuff in here. 
</xsl:if> 
+0

你也可以简单地用这个谓词做一个模板,我会想。 – 2008-10-01 16:40:32

+0

这是完美的。是的,我只需要在同一父母内部抑制重复,我想明确地允许其他父母中的相同元素 - 这很好用,并且比使用按键和Muenchen方法下去的路线简单得多! – 2008-10-02 09:09:42

1

如果只检查(并警告重复的你),你会发现沿线的一个example here

东西:

<xsl:for-each-group select="collection(...)//@id" group-by="."> 
    <xsl:if test="count(current-group()) ne 1"> 
    <xsl:message>Id value <xsl:value-of select="current-grouping-key()"/> is 
     duplicated in files 
     <xsl:value-of select="current-group()/document-uri(/)" separator=" and 
    "/></xsl:message> 
    </xsl:if> 
</xsl:for-each-group> 

进行修改,以选择中“所有节点根“元素。

,去除重复行,你有另一个example here

这将是这样的:

<xsl:stylesheet> 
    <xsl:key name="xyz" match="record[x/y/z]" use="x/y/z" /> 
    <xsl:variable name="noxyzdups" select="/path/to/record[generate-id(.) = generate-id(key('xyz', x/y/z))]" /> 
... 
    <xsl:template ... > 
    <xsl:copy-of "exslt:node-set($noxyzdups)" /> 
    </xsl:template> 
</xsl:stylesheet> 

X/Y/Z是您要做出独特的XPath表达式。它可以是concat(x,' - ',@ y,' - ',z)或任何你想要的。

现在我不确定这两个例子可以很容易地适用于您的案例,但我只是想指出这两个来源,以防万一它有帮助。

1

询问变换的输出是不可能的。跟踪变换的当前状态也是不可能的(即跟踪你在变量中发出的节点)。从根本上说,这不是XSLT的工作原理。无副作用的编程环境的成本之一是你不能做有副作用的事情。好吧。

就你而言,完成此操作的一种方法是构建一个变量,该变量包含所有可以转换为要仅发射一次的输出元素的源元素的列表。然后检查你正在转换的每个节点对这个列表。如果它不在列表中,则发出它。如果它是列表中的第一项,则发出它。否则,不要。