Работаю на VS2015 Community Edition (так же пробовал этот код и на VS2008 Professional Edition). Функция selectSingleNode() возвращает null (E_FAIL).
Для работы с xml создал класс CXmlDocument
// XmlDocument.h
class CXmlDocument
{
public:
CXmlDocument( const CStringW& szXml );
CStringW GetNodeText( const CStringW& szXPath ) const;
private:
CComPtr< MSXML::IXMLDOMDocument > m_Document;
};
// XmlDocument.cpp
CXmlDocument::CXmlDocument( const CStringW& szXml )
{
if ( m_Document.CoCreateInstance( MSXML::CLSID_DOMDocument60 ) != S_OK )
{
return;
}
m_Document->put_validateOnParse( VARIANT_FALSE );
VARIANT_BOOL bIsSuccessful;
m_Document->loadXML( CComBSTR( szXml ), &bIsSuccessful );
}
CStringW CXmlDocument::GetNodeText( const CStringW& szXPath ) const
{
CStringW szResult;
if ( m_Document )
{
CComPtr< MSXML::IXMLDOMNode > node;
if ( m_Document->selectSingleNode( CComBSTR( szXPath ), &node ) == S_OK && node )
{
CComBSTR bstrText;
node->get_text( &bstrText );
szResult = bstrText;
}
}
return szResult;
}
Основной код приложения:
#include "stdafx.h"
#include "XmlDocument.h"
using namespace std;
int main()
{
CoInitialize(NULL);
const CStringW testXml =
L"<?xml version=\"1.0\"?>"
L"<d:propfind xmlns:d=\"DAV:\">"
L"Hello"
L"</d:propfind>";
const CXmlDocument document(testXml);
CStringW result = document.GetNodeText(L"/d:propfind");
printf("Result: %S\n", result);
system("pause");
return 0;
}
И подключаемые заголовки:
// stdafx.h
#ifndef STRICT
#define STRICT
#endif
#include <stdio.h>
#include <tchar.h>
#define _ATL_APARTMENT_THREADED
#define _ATL_NO_AUTOMATIC_NAMESPACE
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
#include <atlbase.h>
#include <atlstr.h>
#include <atlcom.h>
#include <atlctl.h>
#include <ATLComTime.h>
#include <atlcoll.h>
#include <atlfile.h>
#include <atlsafe.h>
#include <commctrl.h>
#include <atlutil.h>
#include <vector>
#include <memory>
#include <map>
#include <set>
#include <assert.h>
using std::tr1::shared_ptr;
using std::tr1::weak_ptr;
using namespace ATL;
#import <msxml6.dll> rename_namespace("MSXML"), named_guids, no_auto_exclude, raw_interfaces_only
using namespace MSXML;
Проблема заключается в том, что при использовании метода GetNodeText() возвращается пустая строка. Дебаг показал, что проблема кроется в использовании функции selectSingleNode(). После вызова она возвращает E_FAIL и ничего не записывает в node. Однако, если убрать namespace из testXml и из запроса XPath, то приложение работает нормально и выводится строка Hello. Поиск по гуглу разумных ответов не дал как задать пространство имен в этом случае. Или же, причина в чем-то другом?
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Здравствуйте! Насколько правильна данная функция по получению имени пользователя с точки зрения выделения и чистки памяти? Нужно ли чистить...