Ian*_*oyd 5 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>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>
Run Code Online (Sandbox Code Playgroud)
所以基本上有三个日期:
使用 MSXML,我可以使用 XPath 查询按这些日期进行查询和过滤:
/NewDataSet/Table[ValidFromDate>"2013-02-12"]
Run Code Online (Sandbox Code Playgroud)
这有效,并返回一个IXMLDOMNodeList包含一个项目:
<Table>
<EmployeeBankGUID>2af49699-579e-4beb-9ab0-a58b4bee3158</EmployeeBankGUID>
<ValidFromDate>2014-02-01T00:00:00-05:00</ValidFromDate>
</Table>
Run Code Online (Sandbox Code Playgroud)
使用 MSXML 的 XPath 查询;Microsoft 在 1990 年代后期创建的 xml 变体,在 W3C 标准化为完全不同形式的 XPath 之前。
DOMDocument doc = new DOMDocument();
//...load the xml...
IXMLDOMNodeList nodes = doc.selectNodes('/NewDataSet/Table[ValidFromDate>"2013-02-12"]');
Run Code Online (Sandbox Code Playgroud)
但是那个版本的 MSXML 并不“符合标准”(因为它是在有标准之前创建的)。自 2005 年以来推荐的一种,遵循标准的一种,唯一具有我需要的功能的是 MSXML 6。
这是一个简单的更改,只需实例化一个DOMDocument60类而不是一个DOMDocument类:
DOMDocument doc = new DOMDocument60();
//...load the xml...
IXMLDOMNodeList nodes = doc.selectNodes('/NewDataSet/Table[ValidFromDate>"2013-02-12"]');
Run Code Online (Sandbox Code Playgroud)
除了相同的 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 查询不起作用?
或者,更好的更好的是,为什么是使用的查询工作不再工作?决定语法错误的决定是什么?他们通过“破坏”查询语法解决了哪些边缘情况?
这是最终的功能代码,几乎是我使用的语言:
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);
Run Code Online (Sandbox Code Playgroud)
XPath 查询日期字符串的“正确”方法是什么?
在 XPath 1.0 中,没有办法处理日期字符串,只能考虑时区支持。至少没有正确的方法来处理它们。如果时区不同,比较字符串将会失败。
或者,更好的是,为什么我的 XPath 查询不起作用?
XPath 1.0 仅在字符串上定义相等运算符,对于大于/小于的值必须转换为数字。
ms:string-compareMSXML 4.0 中引入的用途。
/NewDataSet/Table[
ms:string-compare(ValidFromDate, "2014-02-12T00:00:00-05:00") > 0
]
Run Code Online (Sandbox Code Playgroud)
实现过去工作的“符合标准”的方式是什么?
另一种也适用于其他 XPath 实现的替代方案(我使用 进行了测试xmllint,它使用了libxml)可能是translate删除所有非字符串字符,因此字符串将可以解析为数字:
/NewDataSet/Table[
translate(ValidFromDate, "-:T", "") < translate("2014-02-12T00:00:00-05:00", "-:T", "")
]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8647 次 |
| 最近记录: |