Xml 查找同级dateTime节点的最小/最大值的最短XPath

Xml 查找同级dateTime节点的最小/最大值的最短XPath,xml,datetime,xpath,xpath-2.0,Xml,Datetime,Xpath,Xpath 2.0,我有以下简单的xml: <root> <item> <d>2002-05-30T09:00:00</d> </item> <item> <d>2005-05-30T09:00:00</d> </item> <item> <d>2003-05-30T09:00:00</d> </item> </root>

我有以下简单的xml:

<root>
 <item>
  <d>2002-05-30T09:00:00</d>
 </item>
 <item>
  <d>2005-05-30T09:00:00</d>
 </item>
 <item>
  <d>2003-05-30T09:00:00</d>
 </item>
</root>

2002-05-30T09:00:00
2005-05-30T09:00:00
2003-05-30T09:00:00
现在我想使用XPath查找最小或最大日期时间节点

我目前的解决办法是:

/root/item[not(number(translate(./d, 'TZ:-', '.')) <= number(translate(following-sibling::item, 'TZ:-', '.')))][not(number(translate(./d, 'TZ:-', '.')) <= number(translate(preceding-sibling::item, 'TZ:-', '.')))][1]/d

/root/item[not(number(translate(/d,'TZ:-','.'))如果您事先不知道
项的数量,则无法在XPath 1.0中使用,因为每个具有无节点集参数的函数都会将其参数转换为节点集中的第一个节点,并且顺序比较运算符不能处理字符串

在XPath 2.0中,您可以使用:

max(/root/item/d/xs:dateTime(.))

@neo,您列出的XPath表达式在我测试时不起作用。请尝试其他数据集,您将看到:

<root>
   <item>
      <d>2003-05-30T09:00:00</d>
   </item>
   <item>
      <d>2002-05-30T09:00:00</d>
   </item>
   <item>
      <d>2005-05-30T09:00:00</d>
   </item>
</root>
但是,伪变量$current表明这是不完整的,它应该引用最外层的项,即所有谓词之外的上下文节点。不幸的是,XPath 1.0没有为我们提供一种在堆栈上由内部谓词推送另一个上下文时引用该外部上下文的方法

(我似乎还记得\XSLT的一些实现,例如MSXML,允许您使用扩展功能,如
current(1)
,来实现这一点,但我目前找不到相关信息。无论如何,您要求的是XPath解决方案,
current()
不是XPath。)

在这一点上,我同意Alejandro的观点,即在纯标准XSLT1.0中是不可能的

如果您指定使用XPath的环境,例如XSLT、Javascript或XQuery,我们可能会建议一种有效的方法来获取所需内容。如果是XPath 2.0,Alejandro会给出您的答案

如果您有XQuery 1.0,它应该支持XPath 2.0,因此您可以使用Alejandro的解决方案,使用doc()访问您的输入XML文档:

max(doc("myInput.xml")/root/item/d/xs:dateTime(.))

它对我很有用,但我现在正在寻找一个增强的xpath,即以下数据:

<root>
 <items>
  <item>
   <d>2002-05-30T09:00:00</d>
  </item>
 </items>
 <items>
  <item>
   <d>2005-05-30T09:00:00</d>
  </item>
 </items>
 <items>
  <item>
   <d>2005-05-30T10:00:00</d>
  </item>
 </items>  
</root>

2002-05-30T09:00:00
2005-05-30T09:00:00
2005-05-30T10:00:00

@larsH:general maximum XPath 1.0表达式
$nodes[非($nodes>)
无法在此处使用,因为此字符串值无法转换为数字。如果使用
fn:translate
,则必须对节点集中的每个节点执行函数调用(序列是XSLT 2.0的一种类型),因此您必须预先知道
项的计数:
/root/item[.>=translate(../item[1],'TZ:-','')[.>=translate(../item[2],'TZ:-','')[.>=translate(../item[3],'TZ:-','')]
我必须说,我真的很喜欢XPath 2.0版本,但我只有XPath 1.0可用。虽然这意味着在我的情况下需要做更多的工作,但我也可以在这里使用XQuery。那会是什么样子?如果你可以使用XQuery,它应该包含XPath 2.0。所以你可以使用Alejandro的解决方案:
max(doc(“myInput.xml”)/root/item/d/xs:dateTime()
免责声明:我不是XQuery用户。我刚刚意识到我实际上有可用的XPath 2.0(在YAWL工作流引擎中)因为它在任何地方都使用XQuery。对于这种混淆,我很抱歉,我会接受这两篇文章作为答案,因为你的文章适用于XPath 1.0,Alejandro的文章适用于XPath 2.0。我将选择XPath 2.0解决方案作为我的答案,因为这是我最后使用的解决方案。效果非常好,我非常喜欢这种语法,另请参阅我对另一个的评论回答。@neo:我很高兴它对您有所帮助。现在您知道您有了XQuery 1.0和XPath 2.0,您将发现XPath 1.0有很多改进:在这种情况下,不仅
fn:max
,而且可以使用表达式作为路径中的最后一步。我还重新记录了您的问题。
<root>
 <items>
  <item>
   <d>2002-05-30T09:00:00</d>
  </item>
 </items>
 <items>
  <item>
   <d>2005-05-30T09:00:00</d>
  </item>
 </items>
 <items>
  <item>
   <d>2005-05-30T10:00:00</d>
  </item>
 </items>  
</root>