我的XML看起来像这样:
<foo>
<bar name="a">
<baz name="xyz">
<time>2</time>
<date>3</date>
</baz>
</bar>
<bar name="b">
<baz name="xyz">
<time>2</time>
<date>3</date>
</baz>
</bar>
<bar name="c">
<baz name="xyz">
<time>2</time>
<date>3</date>
</baz>
</bar>
</foo>
我正在编写一个需要像这样运行的XSL:如果所有baz
个孩子都相同,那么doSomething
其他doSomethingElse
。我当前的节点是foo
。
我是XSLT的新手,我知道XSL中的条件。它现在看起来像这样:
<xsl:template match="foo">
<xsl:choose>
<xsl:when test="[My condition]">
doSomething()
</xsl:when>
<xsl:otherwise>
doSomethingElse()
</xsl:otherwise>
</xsl:choose>
</xsl:template>
在当前示例中,它应doSomething()
,因为所有baz
元素都相同。
如果我找到唯一baz
元素的数量,我可以测试它是否等于1。如果是,那么我将doSomething()
其他doSomethingElse()
我该如何实现? MyCondition
应该是什么?
PS:我的XSL版本是1.0
答案 0 :(得分:2)
如果所有
baz
个孩子都相同,那么doSomething
doSomethingElse
。我当前的节点是foo
。
这令人困惑,因为:
baz
不是foo
; 尝试类似:
<xsl:template match="foo">
<xsl:variable name="first-baz" select="(bar/baz)[1]" />
<xsl:choose>
<xsl:when test="bar/baz[date!=$first-baz/date or time!=$first-baz/time]">
<!-- THEY ARE NOT ALL SAME -->
</xsl:when>
<xsl:otherwise>
<!-- THEY ARE ALL SAME -->
</xsl:otherwise>
</xsl:choose>
</xsl:template>
请注意,这假定每个baz
都有date
和time
。否则,您需要测试not(date=$first-baz/date)
等。
另见: http://www.jenitennison.com/xslt/grouping/muenchian.html
现在,假设所有
bar/baz
元素都具有相同的标签(不是 必须date
和time
,但要说a
,b
和c
),那会是什么 该案例的测试属性?
这使得它变得更加复杂。你仍然可以构建一个关键:
<xsl:key name="first-baz" match="foo/bar[1]/baz[1]/*" use="name()" />
然后进行测试:
<xsl:when test="bar/baz/*[. != key('first-baz', name())]">
如果存在baz
的任何子项,其字符串值与同名的第一个baz
的子节点不同,则返回true。
请注意,此处定义的密钥是文档范围的。如果要将测试限制为当前foo
祖先,则必须在密钥中包含其ID。
答案 1 :(得分:0)
如果您想以通用方式执行此操作,那么您实际上正在将XSLT 1.0的功能扩展到其设计限制之外。但这是可以完成的。
编写一个名为deep-equal的命名模板,它将两个元素作为参数,并返回一个包含字符“F”的字符串,当且仅当它们不相等时(为了您的目的)。
可能看起来像这样:
<xsl:template name="deep-equal">
<xsl:param name="a"/>
<xsl:param name="b"/>
<xsl:choose>
<xsl:when test="local-name(a) != local-name(b)">F</xsl:when>
<xsl:when test="namespace-uri(a) != namespace-uri(b)">F</xsl:when>
<xsl:when test="normalize-space(a) != normalize-space(b)">F</xsl:when>
<xsl:when test="count(a/*) != count(b/*)">F</xsl:when>
<xsl:otherwise>
<xsl:variable name="diffs">
<xsl:for-each select="*">
<xsl:variable name="position" select="position()"/>
<xsl:call-template name="deep-equal">
<xsl:with-param name="a" select="."/>
<xsl:with-param name="b" select="$b/*[$position]"/>
</xsl:call-template>
</xsl:for-each>
</xsl:variable>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
将此应用于所有相关元素对:
<xsl:variable name="comparison">
<xsl:for-each select="baz[position() >= 2]">
<xsl:call-template name="deep-equal">
<xsl:with-param name="a" select="../baz[1]"/>
<xsl:with-param name="b" select="."/>
</xsl:call-template>
</xsl:for-each>
</xsl:variable>
测试结果是否包含“F”:
<xsl:if test="contains($comparison, 'F')">...</xsl:if>