Xml XPath查询按日期筛选

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

示例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>
这将起作用,并返回一个包含一项的
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中引入的用法

    /NewDataSet/Table[
      ms:string-compare(ValidFromDate, "2014-02-12T00:00:00-05:00") > 0
    ]
    
    对于(XML)世界的其他部分 什么是“符合标准”的方式来实现以前的工作

    在其他XPath实现中也可以使用的另一种方法是
    将所有非字符串字符翻译掉,这样字符串就可以作为一个数字进行解析:

    /NewDataSet/Table[
      translate(ValidFromDate, "-:T", "") < translate("2014-02-12T00:00:00-05:00", "-:T", "")
    ]
    
    /NewDataSet/Table[
    翻译(从日期起生效,“-:T”,”)
    Reference to undeclared namespace prefix:'ms./NewDataSet/Table[-->ms:string compare(ValidFromDate,“2014-02-12T00:00:00-05:00”)0]我想您必须使用类似于
    doc.setProperty(“SelectionNamespaces”,“xmlns:ms='urn:schemas-microsoft-com:xslt')的内容来注册名称空间
    。这当然可以解释为什么这种功能消失了:
    SelectionNamespaces
    解决了最后一个问题。所以这可能就是问题4的答案。是的,它解释了所有的背景。微软创建了一个很好的规范。但W3C没有采用它,而是提出了一个残缺的规范。12年后,我们就到了。现在我知道这个问题。
    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", "")
    ]