我有一些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检查:元素在模板我想,但我不知道如何来询问输出文件,看是否该元素已经存在。
编辑:忘记预先标记,代码现在应该可以看到!
这要看怎么全系统你想。
即你只关心的是同父的子女,或在同级别文档中任何地方的所有元素(“堂兄弟”,如果你喜欢)或元素的元素...
在第一种情况下,你可以检查前同辈轴,看是否具有相同名称存在的任何其他元素。
<xsl:if test="count(preceding-sibling::node()[name()=name(current())])=0">
... do stuff in here.
</xsl:if>
如果只检查(并警告重复的你),你会发现一个在这里例子
沿着线的东西:
<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>
进行修改,以选择“根”元素内的所有节点。
至于删除重复的线路,你有另一个例子在这里
这将是这样的:
<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)或任何你想要的。
现在,我不知道这两个例子可以很容易地适应你的情况,但我只是想指出这两个来源,如果它帮助。
这是不可能的询问您的转换输出。 它也无法跟踪您的转换(即跟踪哪些节点你发出的一个变量)的当前状态。 从根本上说,这不是XSLT是如何工作的。 一个无副作用的编程环境的成本之一是,你不能做的事情,有副作用。 那好吧。
在你的情况下,实现这一点的办法之一是建立包含所有可能被转化成要一次发射输出元素源元素的列表的变量。 然后检查你正在改变对这个列表中的每个节点。 如果它不在列表中,发射它。 如果它在列表中的第一项,发出它。 否则,没有。