XPATH包含(字符串,字符串)Not Working

时间:2010-10-10 01:44:10

标签: c++ com xpath

我有一个类似于以下内容的XML文件......

<a>
  <b>
    <version>1.0</version>
    <c>
       <Module>foo.EXE</Module>
    </c>
    <c>
       <Module>bar.DLL</Module>
    </c>
  </b>
</a>

我有一个使用MSXML2的COM DLL:调用“selectNodes”的IXMLDOMNode对象...

    CComPtr<MSXML2::IXMLDOMNodeList> oRes = NULL ;
    HRESULT hResult = m_StartNode->selectNodes(sQuery, &oRes) ;

当sQuery为//a/b/c[Module[contains(.,'EXE')]]时,则hResult为E_FAIL且:: GetLastError()返回0.

不可否认,我是XPATH的新手,但为什么不会返回所有包含'EXE'的Module元素的'c'元素。

((编辑)) 其他更简单的XPATH表达式可以工作。例如,//a/b/c按预期返回所有元素。似乎是当我使用'contains()'或'ends-with()'时XPATH失败。

这是一个完整的控制台应用程序,用于演示此问题。

// XMLTest.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#import <msxml3.dll> raw_interfaces_only rename("value", "xmlvalue")

int _tmain(int argc, _TCHAR* argv[])
{
    CoInitialize(NULL);
    CComPtr<MSXML2::IXMLDOMDocument> thedoc;
    thedoc.CoCreateInstance(__uuidof(MSXML2::DOMDocument));
    _variant_t filename(L"c:\\shared\\test\\BlackListSmall.xml");
    VARIANT_BOOL success;
    HRESULT res = thedoc->load(filename, &success);
    _bstr_t sQuery = L"//a/b/c[Module[contains(.,'EXE')]]";
    CComPtr<MSXML2::IXMLDOMNodeList> oRes;
    thedoc->selectNodes(sQuery, &oRes);
    thedoc = NULL;
    oRes = NULL;
    CoUninitialize();
    return 0;
}

这是stdafx.h的内容

#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#ifndef STRICT
#define STRICT
#endif
#define _ATL_APARTMENT_THREADED
#define _ATL_NO_AUTOMATIC_NAMESPACE
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS  // some CString constructors will be explicit
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>
using namespace ATL;

BTW,当我运行它并进入selectNodes()调用时,我在调试器输出窗口中收到三条消息......

First-chance exception at 0x7564fbae in XMLTest.exe: 0xE0000001: 0xe0000001.
First-chance exception at 0x7564fbae in XMLTest.exe: 0xE0000001: 0xe0000001.
First-chance exception at 0x7564fbae in XMLTest.exe: 0xE0000001: 0xe0000001.

...当我打破所有异常时,callstack没有提供真实的信息。

<(>(最终编辑))我将答案授予Dimitre,见下文。以下是我根据他的回答对我的示例程序所做的更改......

#import <msxml4.dll> raw_interfaces_only rename("value", "xmlvalue")
...
CComPtr<MSXML2::IXMLDOMDocument2> thedoc; //changed from IXMLDOMDocument
...
HRESULT res = thedoc->load(filename, &success);    // unchanged
_bstr_t lang = L"SelectionLanguage";  // inserted 
_variant_t xpathlang = L"XPath";      // inserted
thedoc->setProperty(lang,xpathlang);  // inserted
_bstr_t sQuery = L"//a/b/c[Module[contains(.,'EXE')]]";  //unchanged
...

再次感谢Dimitre

2 个答案:

答案 0 :(得分:1)

您必须在文档对象上发布

setProperty("SelectionLanguage", "XPath");

在使用XPath表达式调用SelectNodes() methd之前。

默认值不是XPath,而是一些早期的选择语言。

答案 1 :(得分:0)

你想要:

"//a/b/c[contains(./Module/text(),'EXE')]"

假设您希望具有Module子元素的c元素具有包含字符串'EXE'的文本