XPath查询在IXMLDOMDocument2中不工作,但通过在线XPath测试器



在下面的XML中,我尝试使用XPath查询来选择具有RenderingInfo/Task = StartRemoteSessionRdpClientBegin的第一个<Event>节点。

<Events>
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Guid="{9e814aad-3204-11d2-9a82-006008a86939}" />
<EventID>0</EventID>
</System>
<EventData>
<Data Name="EventVersion">0</Data>
<Data Name="Reserved">0</Data>
<Data Name="PartitionType">       0</Data>
</EventData>
<RenderingInfo Culture="en-US">
<Opcode>PartitionInfoExtensionV2</Opcode>
<Provider>MSNT_SystemTrace</Provider>
<EventName xmlns="http://schemas.microsoft.com/win/2004/08/events/trace">EventTrace</EventName>
</RenderingInfo>
<ExtendedTracingInfo xmlns="http://schemas.microsoft.com/win/2004/08/events/trace">
<EventGuid>{68fdd900-4a3e-11d1-84f4-0000f80464e3}</EventGuid>
</ExtendedTracingInfo>
</Event>
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft.Windows.HVSI.Manager" Guid="{5e3f60ef-a60f-45a9-84ae-e224f761baa3}" />
<EventID>0</EventID>
</System>
<EventData>
<Data Name="ContainerName">2fb583e6-3769-4465-9de0-ce56a1aa84c4</Data>
<Data Name="RDPSessionID">{24259afa-2028-4206-9856-257ea519bfdd}</Data>
<Data Name="PartA_PrivTags">16777216</Data>
</EventData>
<RenderingInfo Culture="en-US">
<Task>StartRemoteSessionRdpClientBegin</Task>
</RenderingInfo>
</Event>
</Events>

从我看过的W3School的例子中,我认为这应该可以用XPath查询:/Events/Event[RenderingInfo/Task="StartRemoteSessionRdpClientBegin"].

我在https://www.uccollabing.com/free-online-xpath-tester-evaluator-tool/上尝试了我的XML,它似乎在那里工作,这让我怀疑我的代码有问题。简单的查询工作,例如/Events/Events/*

我的上述查询工作吗?

HRESULT SearchTraceFile(std::wstring fileName)
{
HRESULT hr = S_OK;
_bstr_t xPath = L"/Events/Event[RenderingInfo/Task="StartRemoteSessionRdpClientBegin"]";
wprintf(L"Query path: %sn", static_cast<wchar_t*>(xPath));
RETURN_IF_FAILED(CoInitialize(NULL));
wrl::ComPtr<IXMLDOMDocument2> xmlDoc;
RETURN_IF_FAILED(CoCreateInstance(
CLSID_DOMDocument60,
nullptr,
CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument2, (void**)&xmlDoc));
_variant_t localFileName(fileName.c_str());
VARIANT_BOOL successful = VARIANT_FALSE;
RETURN_IF_FAILED(xmlDoc->load(localFileName, &successful));
RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_DATA), (successful != VARIANT_TRUE));
_variant_t varXPath(L"XPath");
xmlDoc->setProperty(L"SelectionLanguage", varXPath);
xmlDoc->setProperty(L"MaxElementDepth", CComVariant(10));
wrl::ComPtr<IXMLDOMNodeList> events;
wrl::ComPtr<IXMLDOMNode> spTaskNode;
hr = xmlDoc->selectSingleNode(xPath, &spTaskNode);
if (FAILED(hr)) return hr;
if (S_FALSE == hr)
{
wprintf(L"Not foundn");
return S_OK;
}
BSTR value = NULL;
hr = spTaskNode->get_text(&value);
if (FAILED(hr)) wprintf(L"get_text failed 0x%08xn", hr);
else wprintf(L"get_text succeddedn");
wprintf(L"value:n%sn", value);
::SysFreeString(value);
return hr;
}

XML涉及到名称空间,因此必须在XPath查询中考虑到这一点。这是在MSDN上记录的:

使用XPath查询DOM时指定Namespace

例如:

HRESULT SearchTraceFile(std::wstring fileName)
{
_bstr_t xPath = L"/Events/e:Event[e:RenderingInfo/e:Task="StartRemoteSessionRdpClientBegin"]"; // <-- NOTE THE 'e:' PREFIXES!
wprintf(L"Query path: %sn", static_cast<wchar_t*>(xPath));
RETURN_IF_FAILED(CoInitialize(NULL));
wrl::ComPtr<IXMLDOMDocument2> xmlDoc;
RETURN_IF_FAILED(CoCreateInstance(
CLSID_DOMDocument60,
nullptr,
CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument2, (void**)&xmlDoc));
_variant_t localFileName(fileName.c_str());
VARIANT_BOOL successful = VARIANT_FALSE;
RETURN_IF_FAILED(xmlDoc->load(localFileName, &successful));
RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_DATA), (successful != VARIANT_TRUE));
xmlDoc->setProperty(L"SelectionLanguage", _variant_t(L"XPath"));
xmlDoc->setProperty(L"SelectionNamespaces", _variant_t(L"xmlns:e='http://schemas.microsoft.com/win/2004/08/events/event'")); // <-- ADD THIS!
xmlDoc->setProperty(L"MaxElementDepth", _variant_t(10));
wrl::ComPtr<IXMLDOMNodeList> events;
wrl::ComPtr<IXMLDOMNode> spTaskNode;
HRESULT hr = xmlDoc->selectSingleNode(xPath, &spTaskNode);
if (FAILED(hr)) {
wprintf(L"selectSingleNode failed 0x%08xn", hr);
return hr;
}
if (S_FALSE == hr)
{
wprintf(L"Not foundn");
return S_OK;
}
_bstr_t value;
hr = spTaskNode->get_text(value.GetAddress());
if (FAILED(hr)) {
wprintf(L"get_text failed 0x%08xn", hr);
return hr;
}
wprintf(L"get_text succeedednvalue:n%sn", static_cast<wchar_t*>(value));
return S_OK;
}

最新更新