0

假设存在允许使用 XSLT 来指定 XML 消息上的某个谓词的软件系统。具体来说:将输入文档转换为以下形式的输出文档:(<predicate>true</predicate><predicate>false</predicate>)。

对于一些简单的情况(如message containsXPath),这相当简单,但我现在需要为以下内容编写一个 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变量是从其中删除change/item[2]/something了任何现有something子树,然后可能类似于not(deep-equal($before,$after))...?

这里的任何人都知道如何使用 XSLT 2.0 做到这一点,因为我怀疑这在 XSLT 1.0 中是完全不可能的?

4

1 回答 1

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-somethingitemsomethingnot(deep-equal($before,$after))

于 2013-07-29T15:36:54.567 回答