假设存在一个软件系统,该系统允许使用XSLT在XML消息上指定某个谓词。具体来说:将输入文档转换为以下格式的输出文档:<predicate>true</predicate>
(或<predicate>false</predicate>
)。
对于一些简单的情况(如 message contains XPath
),这是相当简单的,但我现在需要为以下内容编写一个XSLT:
<change>
<!-- state before change -->
<item>
<name>
<first>...</first>
<last>...</last>
</name>
<something>
...
</something>
</item>
<!-- state after change -->
<item>
<name>
<first>...</first>
<last>...</last>
</name>
<something>
...
</something>
</item>
</change>
如果符合以下情况,我想返回<predicate>true</predicate>
来获取变异的定义:
something
数据的子树(因为此部分是可选的),所以基本上change/item[1]/something | change/item[2]/something
,和 something
数据的前后状态并不相同。第二部分可能类似于以下伪代码:$before
变量change/item[1]/something
,其中已删除任何现有的something
子树,$after
变量为{{1}从任何现有的change/item[2]/something
子树中删除它,然后可能像something
......?
任何人都知道如何使用XSLT 2.0来实现这一点,因为我怀疑在XSLT 1.0中完全不可能这样做?
答案 0 :(得分:0)
尝试
<xsl:template match="change">
<xsl:choose>
<xsl:when test="item[1]/something | item[2]/something">
<xsl:variable name="before" as="element(item)">
<xsl:apply-templates select="item[1]" mode="rs"/>
</xsl:variable>
<xsl:variable name="after" as="element(item)">
<xsl:apply-templates select="item[2]" mode="rs"/>
</xsl:variable>
<predicate><xsl:value-of select="not(deep-equal($before,$after))"/></predicate>
</xsl:when>
<xsl:otherwise>
<predicate>false</predicate>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="@* | node()" mode="rs">
<xsl:copy>
<xsl:apply-templates select="@* , node()" mode="rs"/>
</xsl:copy>
</xsl:template>
<xsl:template match="something" mode="rs"/>
未经测试但应该给你一个想法。它基本上在mode="rs"
(remove-something
)上对两个item
元素进行转换,以剥离something
元素,然后执行您发布的比较(not(deep-equal($before,$after))
)。