c++ - XPATH 包含(字符串,字符串)不工作

标签 c++ com xpath

我有一个如下所示的 XML 文件...

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

我有一个 COM DLL,它使用 MSXML2:IXMLDOMNode 对象调用“selectNodes”,例如...

    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”的模块元素的“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;

顺便说一句,当我运行它并调用 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.

...当我中断所有异常时,调用堆栈不提供任何真实信息。

((Final Edit)) 我把答案交给了 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
...

再次感谢迪米特雷

最佳答案

你必须在文档对象上发出这个:

setProperty("SelectionLanguage", "XPath");

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

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

关于c++ - XPATH 包含(字符串,字符串)不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3898651/

相关文章:

c++ - 自动跟踪程序执行

c++ - 为什么我不能打印出我的宏创建结构的所有成员名称?

c++ - IWebBrowser2 接口(interface)依赖关系图

python - 使用 lxml 和 xpath 从网页获取文本

c++ - 是否可以创建这样的 C++ 宏来将您的标准(继承的)类包装到应用程序中?

c++ - 将 C++ 库添加到 Eclipse C++ 项目

c# - 如何将数据从非托管应用程序传递到 C# COM DLL

com - 为什么在 C++ 中的 Windows COM 编程中有这么多方法显式解析为全局命名空间?

c# - xPath 获取具有特定值的元素的兄弟值

sql-server - 从先前转换为XML的表列中提取多个值