Xml XPath查询按日期筛选
我有一些基于日期查询节点的示例XML 示例XML文档:Xml XPath查询按日期筛选,xml,xpath,msxml,msxml6,Xml,Xpath,Msxml,Msxml6,我有一些基于日期查询节点的示例XML 示例XML文档: <?xml version="1.0" encoding="UTF-16" standalone="yes"?> <NewDataSet> <Table> <EmployeeBankGUID>dc396ebe-c8a4-4a7f-85b5-b43c1890d6bc</EmployeeBankGUID> <ValidFromDate>
<?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>
这将起作用,并返回一个包含一项的IXMLDOMNodeList
:
<Table>
<EmployeeBankGUID>2af49699-579e-4beb-9ab0-a58b4bee3158</EmployeeBankGUID>
<ValidFromDate>2014-02-01T00:00:00-05:00</ValidFromDate>
</Table>
但该版本的MSXML并不“符合标准”(因为它是在标准出现之前创建的)。是MSXML6
这是一个简单的更改,只需实例化一个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>“2014-02-12T00:00:00-05:00”]
/NewDataSet/Table[ValidFromDateXPath不知道日期 使用XPath查询日期字符串的“正确”方法是什么 在XPath 1.0中,没有处理日期字符串的方法,只考虑时区支持。至少没有正确的方法来处理它们。如果时区不同,比较字符串将失败 比较字符串 或者,更好的是,为什么我的XPath查询不起作用 XPath 1.0仅在字符串上定义相等运算符,用于大于/小于值 MSXML 4.0中引入的用法
对于(XML)世界的其他部分 什么是“符合标准”的方式来实现以前的工作 在其他XPath实现中也可以使用的另一种方法是/NewDataSet/Table[ ms:string-compare(ValidFromDate, "2014-02-12T00:00:00-05:00") > 0 ]
将所有非字符串字符翻译掉,这样字符串就可以作为一个数字进行解析:
/NewDataSet/Table[ translate(ValidFromDate, "-:T", "") < translate("2014-02-12T00:00:00-05:00", "-:T", "") ]
Reference to undeclared namespace prefix:'ms./NewDataSet/Table[-->ms:string compare(ValidFromDate,“2014-02-12T00:00:00-05:00”)0]我想您必须使用类似于/NewDataSet/Table[ 翻译(从日期起生效,“-:T”,”)
。这当然可以解释为什么这种功能消失了:doc.setProperty(“SelectionNamespaces”,“xmlns:ms='urn:schemas-microsoft-com:xslt')的内容来注册名称空间
解决了最后一个问题。所以这可能就是问题4的答案。是的,它解释了所有的背景。微软创建了一个很好的规范。但W3C没有采用它,而是提出了一个残缺的规范。12年后,我们就到了。现在我知道这个问题。SelectionNamespaces
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);
/NewDataSet/Table[ ms:string-compare(ValidFromDate, "2014-02-12T00:00:00-05:00") > 0 ]
/NewDataSet/Table[ translate(ValidFromDate, "-:T", "") < translate("2014-02-12T00:00:00-05:00", "-:T", "") ]