gpt4 book ai didi

xml - 按日期过滤 XPath 查询

转载 作者:数据小太阳 更新时间:2023-10-29 02:06:26 24 4
gpt4 key购买 nike

我有一些示例 XML,我在其中查询基于日期的节点。

示例 XML 文档:

<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
<NewDataSet>
<Table>
<EmployeeBankGUID>dc396ebe-c8a4-4a7f-85b5-b43c1890d6bc</EmployeeBankGUID>
<ValidFromDate>2012-02-01T00:00:00-05:00</ValidFromDate>
</Table>
<Table>
<EmployeeBankGUID>2406a5aa-0246-4cd7-bba5-bb17a993042b</EmployeeBankGUID>
<ValidFromDate>2013-02-01T00:00:00-05:00</ValidFromDate>
</Table>
<Table>
<EmployeeBankGUID>2af49699-579e-4beb-9ab0-a58b4bee3158</EmployeeBankGUID>
<ValidFromDate>2014-02-01T00:00:00-05:00</ValidFromDate>
</Table>
</NewDataSet>

所以基本上有三个日期:

  • 2/1/2012
  • 2013 年 2 月 1 日
  • 2/1/2014

使用 MSXML,我可以使用 XPath 查询按这些日期进行查询和过滤:

/NewDataSet/Table[ValidFromDate>"2013-02-12"]

这有效,并返回 IXMLDOMNodeList包含一项:

<Table>
<EmployeeBankGUID>2af49699-579e-4beb-9ab0-a58b4bee3158</EmployeeBankGUID>
<ValidFromDate>2014-02-01T00:00:00-05:00</ValidFromDate>
</Table>

除了它不再起作用

使用 MSXML 的 XPath 查询;在 W3C 对完全不同形式的 XPath 进行标准化之前,Microsoft 在 1990 年代后期创建的 xml 变体。

DOMDocument doc = new DOMDocument();
//...load the xml...
IXMLDOMNodeList nodes = doc.selectNodes('/NewDataSet/Table[ValidFromDate>"2013-02-12"]');

但该版本的 MSXML 不是“符合标准”(因为它是在有标准之前创建的)。 Since 2005 the recommended one, the one that follows the standards, the only one that has features I require是 MSXML 6。

这是一个简单的更改,只需实例化一个 DOMDocument60类而不是 DOMDocument类:

DOMDocument doc = new DOMDocument60();
//...load the xml...
IXMLDOMNodeList nodes = doc.selectNodes('/NewDataSet/Table[ValidFromDate>"2013-02-12"]');

除了相同的 XPath 查询不返回任何内容。

按日期过滤值的“符合标准”方法是什么?

假设它是一个字符串,你说

您可能认为我可能认为 XML 正在处理 2013-02-01T00:00:00-05:00作为某种特殊日期,而实际上它是一个字符串。所以也许我应该将其视为字符串比较。

这会起作用,但它不起作用。没有字符串比较工作:

  • /NewDataSet/Table[ValidFromDate<"a"]不返回任何节点
  • /NewDataSet/Table[ValidFromDate>"a"]不返回任何节点
  • /NewDataSet/Table[ValidFromDate!="a"]返回所有节点
  • /NewDataSet/Table[ValidFromDate>"2014-02-12T00:00:00-05:00"]不返回任何节点
  • /NewDataSet/Table[ValidFromDate<"2014-02-12T00:00:00-05:00"]不返回任何节点
  • /NewDataSet/Table[ValidFromDate!="2014-02-12T00:00:00-05:00"]不返回任何节点

所以,我们有它

什么是“符合标准”的方法来实现过去的工作?

XPath 查询日期字符串的“正确”方法是什么?

或者,更好的是,为什么我的 XPath 查询不起作用?

或者,更好的是更好,为什么曾经有效的查询不再有效?决定语法错误的决定是什么。他们通过“破坏”查询语法解决了哪些极端情况?

MSXML6 兼容版本

这是最终的功能代码,几乎是我使用的语言:

DOMDocument60 GetXml(String url)
{
XmlHttpRequest xml = CoServerXMLHTTP60.Create();
xml.Open('GET', url, False, '', '');
xml.Send(EmptyParam);

DOMDocument60 doc = xml.responseXML AS DOMDocument60;

//MSXML6 removed all kinds of features originally present (thanks W3C)
//Need to use Microsoft's proprietary extensions to get some of it back (thanks W3C)
doc.setProperty('SelectionNamespaces', 'xmlns:ms="urn:schemas-microsoft-com:xslt"');

return doc;
}


DOMDocument doc = GetXml('http://example.com/GetBanks.ashx?employeeID=12345');

//Finds future banks.

//Only works in MSXML3; intentionally broken in MSXML6 (thanks W3C):
//String qry = '/NewDataSet/Table[ValidFromDate > "2014-02-12"]';

//MSXML6 compatible version of doing the above (send complaints to W3C);
String qry = '/NewDataSet/Table[ms:string-compare(ValidFromDate, "2014-02-12") >= 0]';

IXMLDOMNodeList nodes = doc.selectNodes(qry);

最佳答案

XPath 不支持日期

What is the "correct" way to XPath query for date strings?

在 XPath 1.0 中,无法处理日期字符串,只能考虑时区支持。至少没有正确的方法来处理它们。如果时区不同,比较字符串将失败。

比较字符串

Or, better yet, why are my XPath queries not working?

XPath 1.0 仅在字符串上定义相等运算符,用于大于/小于值 have to be converted to numbers .

使用ms:string-compare这是在 MSXML 4.0 中引入的。

/NewDataSet/Table[
ms:string-compare(ValidFromDate, "2014-02-12T00:00:00-05:00") > 0
]

对于 (XML) 世界的其余部分

What is the "standards compliant" way to achieve what used to work?

一个也适用于其他 XPath 实现的替代方案(我使用 xmllint 测试了它,它使用 libxml)可能是 翻译所有非字符串字符,因此字符串将被解析为数字:

/NewDataSet/Table[
translate(ValidFromDate, "-:T", "") < translate("2014-02-12T00:00:00-05:00", "-:T", "")
]

关于xml - 按日期过滤 XPath 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21663262/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com