1

我有以下 XML:

<STATUSLIST>
    <STATUS>
        <TYPE VALUE="1"/>
        <DATE>19910000</DATE>
    </STATUS>
    <STATUS>
        <TYPE VALUE="1"/>
        <DATE>19470000</DATE>
    </STATUS>
    <STATUS>
        <TYPE VALUE="2"/>
        <DATE>19470000</DATE>
    </STATUS>
</STATUSLIST>

我想匹配STATUSwhereTYPE/@VALUE = '2'not(//STATUSLIST/STATUS/DATE > DATE). 在这种情况下,它将是 3rd STATUS

当我应用具有最新日期的类型时,我什么也得不到,因为它不能同时匹配两者。我想要的是匹配第TYPE/@VALUE = '2'一个,并在那场比赛中获得最新日期的那个。

有什么线索吗?

干杯,

图诺

4

3 回答 3

1

我的解决方案:STATUS[TYPE/@VALUE = '2'][not(//STATUSLIST/STATUS[TYPE/@VALUE = '2']/DATE > DATE)].

于 2013-08-22T09:07:51.470 回答
0

虽然您自己的解决方案STATUS[TYPE/@VALUE = '2'][not(//STATUSLIST/STATUS[TYPE/@VALUE = '2']/DATE > DATE)]可行,但对于大量条目来说并不是特别有效,因为您将每个条目STATUS与其他条目进行比较STATUS,因此 O(N 2 )。更有效的方法是将其实现为尾递归函数(如您所说的使用 XSLT 2.0),如下所示:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
                xmlns:local="urn:local" exclude-result-prefixes="local">

  <xsl:function name="local:latestByDate" as="item()*">
    <xsl:param name="seq" as="item()*"/>
    <xsl:sequence select="local:latestByDate($seq, ())" />
  </xsl:function>

  <xsl:function name="local:latestByDate" as="item()*">
    <xsl:param name="seq" as="item()*" />
    <xsl:param name="maxSoFar" as="item()*" />
    <xsl:choose>
      <xsl:when test="$seq">
        <!-- calculate the new maxSoFar, comparing the current max with
             the first item in $seq.  Note the use of not(x<=y) instead of
             x>y, so the test is true if $maxSoFar is the empty sequence -->
        <xsl:variable name="newMax"
                      select="if(not($seq[1]/DATE &lt;= $maxSoFar/DATE))
                              then $seq[1] else $maxSoFar"/>
        <xsl:sequence select="local:latestByDate(
                                 $seq[position() gt 1], $newMax)" />
      </xsl:when>
      <xsl:otherwise>
        <!-- we have reached the end of $seq, return the max -->
        <xsl:sequence select="$maxSoFar" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:function>

  <!-- example of how to call the function -->
  <xsl:template match="/*">
    <xsl:copy-of select="local:latestByDate(STATUS[TYPE/@VALUE='2'])" />
  </xsl:template>
</xsl:stylesheet>

此函数对节点列表进行单次传递(因此 O(N)),跟踪输入序列中哪个元素具有最新的每一步DATE

于 2013-08-22T11:03:38.917 回答
0

如果我正确理解了您想要的内容,那么由于缺少最大功能,您无法在 XPath v1 中完成所有这些操作。因此,获取STATUS具有所需 TYPE 的所有元素:

/STATUSLIST/STATUS[TYPE/@VALUE=2]

然后在调用环境中排序或最大化函数。

于 2013-08-22T07:49:58.090 回答