MSXML: Как получить Root элемент?
27.07.2011, 02:20. Показов 3227. Ответов 0
Загружаю в XML документ:
C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| #include <msxml6.h>
// ..
CComPtr<IXMLDOMDocument> spXMLDOM;
CComPtr<IXMLDOMElement> spRoot;
VARIANT_BOOL varStatus;
HRESULT hr = spXMLDOM.CoCreateInstance(__uuidof(DOMDocument));
if ( FAILED(hr) ) throw "Unable to create XML parser object";
if ( spXMLDOM.p == NULL ) throw "Unable to create XML parser object";
CComBSTR bstrXML = ::SysAllocString(L"<root attrib=\"text\"><a id = \"1\"/><a id = \"2\"/></root>");
hr = spXMLDOM->loadXML(bstrXML, &varStatus);
if ( FAILED(hr) )
throw "Failed to load DOM";
if ( varStatus != VARIANT_TRUE)
throw "Failed to load DOM"; |
|
Хочу получить Root элемент:
C++ | 1
| spRoot = spXMLDOM->GetdocumentElement(); |
|
или
spXMLDOM->get_root(&spElement);[/CPP]
Получаю ошибку:
C++ | 1
2
3
4
5
| 1>d:\1\project-c++\savedom\savedom\xmlparser.cpp(85) : error C2039: get_root: не является членом "ATL::_NoAddRefReleaseOnCComPtr<T>"
1> with
1> [
1> T=IXMLDOMDocument
1> ] |
|
C++ | 1
2
3
4
5
| 1>d:\1\project-c++\savedom\savedom\xmlparser.cpp(86) : error C2039: GetdocumentElement: не является членом "ATL::_NoAddRefReleaseOnCComPtr<T>"
1> with
1> [
1> T=IXMLDOMDocument
1> ] |
|
Добавлено через 5 часов 45 минут
Написал класс для инкапсуляции работы с MSXML через Smart:
C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
| // XMLParser.h
#pragma once
#ifndef __XMLPARSER_H_
#define __XMLPARSER_H_
#include <tchar.h>
#include <atlbase.h>
#include <objbase.h>
#import <msxml6.dll> rename_namespace(_T("MSXML"))
#include <msxml6.h>
class CXMLParser
{
public:
CXMLParser():bAppendRoot(FALSE)
{
CreateAndInitDOM();
}
~CXMLParser()
{}
// Ф-ция загрузки XML документа
HRESULT LoadXMLFromFile( PCWSTR wsxFile );
// Ф-ция загрузки XML из строки
HRESULT LoadXML( PCWSTR wsxXML );
// Ф-ция сохраняет XML документа
HRESULT Save( PCWSTR wsxFile );
// Ф-ция возвращает текст XML документа
HRESULT GetXML( _bstr_t &bstrXML );
// Ф-ция возвращеает Root-элемент XML документа
HRESULT GetDocumentElement( MSXML::IXMLDOMElementPtr &spElement);
// Ф-ция для создания эксемпляра DOM
HRESULT CreateAndInitDOM();
// Ф-ция создания нового элемента дерева(закрепляет BSTR за вызывающим)
HRESULT CreateElement( PCWSTR wsxName, MSXML::IXMLDOMElementPtr &spElement );
// Ф-ция добавления потомка к родительскому узлу
HRESULT AppendChildToParent( MSXML::IXMLDOMNode *pChild, MSXML::IXMLDOMNode *pParent );
// Ф-ция добавления родительского узлу к документу
HRESULT AppendRoot( MSXML::IXMLDOMNode *pRoot);
// Ф-ция создания и добавления processing instruction для документа
HRESULT CreateAndAddPINode( PCWSTR wszTarget, PCWSTR wszData );
// Ф-ция создания и добавления комментария для узла документа
HRESULT CreateAndAddCommentNode( PCWSTR wszComment);
// Ф-ция создания и добавления атрибута к родительскому узлу
HRESULT CreateAndAddAttributeNode( PCWSTR wszName,
_variant_t varValue,
MSXML::IXMLDOMNode *pParent );
// Ф-ция создания и добавления текстового узла к родительскому узлу
HRESULT CreateAndAddTextNode( PCWSTR wszText, MSXML::IXMLDOMNode *pParent );
//
HRESULT AddTextNode( PCWSTR wszText, MSXML::IXMLDOMNode *pParent );
// Ф-ция создания и добавления CDATA узла к родительскому
HRESULT CreateAndAddCDATANode( PCWSTR wszCDATA, MSXML::IXMLDOMNode *pParent );
// Ф-ция создания и добавления нового элемента к родительскому узлу и,
// если нужно, то передать созданый элемент вызвавшему
HRESULT CreateAndAddElementNode( PCWSTR wszName,
PCWSTR wszNewLine,
MSXML::IXMLDOMNode *pParent,
MSXML::IXMLDOMElement **ppElement = NULL);
// Ф-ция создания фрагмента XML документа
HRESULT CreateDocumentFragment( MSXML::IXMLDOMDocumentFragmentPtr &docFrag );
MSXML::IXMLDOMDocumentPtr spXMLDOM;
protected:
BOOL bAppendRoot;
private:
};
#endif // __XMLPARSER_H_ |
|
C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
| // CXMLParse.cpp
#include "stdafx.h"
#include "XMLParser.h"
HRESULT CXMLParser::LoadXMLFromFile( PCWSTR wsxFile )
{
HRESULT hr = S_OK;
if ( spXMLDOM->load( wsxFile ) != VARIANT_TRUE)
throw "Failed to load DOM from file";
return hr;
}
HRESULT CXMLParser::LoadXML( PCWSTR wsxXML )
{
HRESULT hr = S_OK;
if ( spXMLDOM->loadXML( wsxXML ) != VARIANT_TRUE)
throw "Failed to load DOM";
return hr;
}
HRESULT CXMLParser::Save( PCWSTR wsxFile )
{
HRESULT hr = S_OK;
if ( spXMLDOM->save( wsxFile ) != VARIANT_FALSE )
throw "Failed to load DOM from file";
return hr;
}
HRESULT CXMLParser::GetXML( _bstr_t &bstrXML )
{
HRESULT hr = S_OK;
bstrXML = spXMLDOM->xml;
if ( !bstrXML )
throw "Failed to get XML text from XML document";
return hr;
}
HRESULT CXMLParser::GetDocumentElement( MSXML::IXMLDOMElementPtr &spElement )
{
HRESULT hr = S_OK;
spElement = spXMLDOM->documentElement;
if ( !spElement )
throw "Failed to get root from XML document";
return hr;
}
HRESULT CXMLParser::CreateAndInitDOM()
{
HRESULT hr = spXMLDOM.CreateInstance( __uuidof(DOMDocument), NULL, CLSCTX_INPROC_SERVER );
if ( FAILED( hr ) )
throw "(CreateAndInitDOM)Unable to create XML parser object";
else
{
spXMLDOM->async = VARIANT_FALSE;
spXMLDOM->validateOnParse = VARIANT_FALSE;
spXMLDOM->resolveExternals = VARIANT_FALSE;
spXMLDOM->preserveWhiteSpace = VARIANT_TRUE;
}
return hr;
}
HRESULT CXMLParser::CreateElement( PCWSTR wsxName, MSXML::IXMLDOMElementPtr &spElement )
{
HRESULT hr = S_OK;
spElement = NULL;
spElement = spXMLDOM->createElement( wsxName );
if ( !spElement )
throw "(CreateElement)Unable to create XML element node";
return hr;
}
HRESULT CXMLParser::CreateAndAddElementNode( PCWSTR wszName, PCWSTR wszNewLine,
MSXML::IXMLDOMNode *pParent,
MSXML::IXMLDOMElement **ppElement /* = NULL */)
{
HRESULT hr = S_OK;
MSXML::IXMLDOMNodePtr spParent = pParent;
MSXML::IXMLDOMElementPtr spElement = NULL;
if ( !spParent )
throw "(CreateAndAddElementNode)Unable to query for element XML node interface";
hr = CreateElement( wszName, spElement );
if ( FAILED(hr) )
throw "(CreateAndAddElementNode)Unable to create XML element";
hr = CreateAndAddTextNode( wszNewLine, spParent );
if ( FAILED(hr) )
throw "(CreateAndAddElementNode)Unable to create XML element";
//pParent->appendChild( spElement );
hr = AppendChildToParent( spElement, spParent );
if ( FAILED(hr) )
throw "(CreateAndAddElementNode)Unable to create XML element";
if ( ppElement )
*ppElement = spElement;
return hr;
}
HRESULT CXMLParser::AppendChildToParent( MSXML::IXMLDOMNode *pChild, MSXML::IXMLDOMNode *pParent )
{
HRESULT hr = S_OK;
//pParent->appendChild( pChild );
MSXML::IXMLDOMNodePtr spChildOut = NULL;
spChildOut = pParent->appendChild( pChild );
if ( !spChildOut )
throw "(AppendChildToParent)Unable to move XML node";
return hr;
}
HRESULT CXMLParser::AppendRoot( MSXML::IXMLDOMNode *pChild )
{
if ( bAppendRoot )
return FALSE;
bAppendRoot = TRUE;
HRESULT hr = S_OK;
MSXML::IXMLDOMNodePtr spChildOut = NULL;
spChildOut = spXMLDOM->appendChild( pChild );
if ( !spChildOut )
throw "(AppendChildToParent)Unable to move XML node";
return hr;
}
HRESULT CXMLParser::CreateAndAddPINode( PCWSTR wszTarget, PCWSTR wszData )
{
HRESULT hr = S_OK;
MSXML::IXMLDOMProcessingInstructionPtr spPI = NULL;
spPI = spXMLDOM->createProcessingInstruction( wszTarget, wszData );
if ( !spPI )
throw "(CreateAndAddPINode)Unable to create processing instruction";
hr = AppendChildToParent( spPI, spXMLDOM );
if ( FAILED(hr) )
throw "(CreateAndAddPINode)Unable to add processing instruction";
return hr;
}
HRESULT CXMLParser::CreateAndAddCommentNode( PCWSTR wszComment )
{
HRESULT hr = S_OK;
MSXML::IXMLDOMCommentPtr spComment = NULL;
spComment = spXMLDOM->createComment( wszComment );
if ( !spComment )
throw "(CreateAndAddCommentNode)Unable to create comment XML node";
hr = AppendChildToParent( spComment, spXMLDOM );
if ( FAILED(hr) )
throw "(CreateAndAddCommentNode)Unable to add comment XML node";
return hr;
}
HRESULT CXMLParser::CreateAndAddAttributeNode( PCWSTR wszName,
_variant_t varValue,
MSXML::IXMLDOMNode *pParent )
{
HRESULT hr = S_OK;
MSXML::IXMLDOMElementPtr spParent = pParent;
MSXML::IXMLDOMAttributePtr spAttribute = NULL;
MSXML::IXMLDOMAttributePtr spAttributeOut = NULL;
spAttribute = spXMLDOM->createAttribute( wszName );
if( !spAttribute )
throw "(CreateAndAddAttributeNode)Unable to create attribute";
spAttribute->value = varValue;
/*spAttributeOut = */spParent->setAttributeNode( spAttribute );
// if( !spAttributeOut )
// throw "(CreateAndAddAttributeNode)Unable to create attribute";
return hr;
}
HRESULT CXMLParser::CreateAndAddTextNode( PCWSTR wszText,
MSXML::IXMLDOMNode *pParent )
{
HRESULT hr = S_OK;
/* pParent->appendChild( spXMLDOM->createTextNode(wszText) ); */
MSXML::IXMLDOMTextPtr spText = NULL;
spText = spXMLDOM->createTextNode( wszText );
if ( !spText )
throw "(CreateAndAddTextNode)Unable to create attribute";
hr = AppendChildToParent(spText, pParent);
if ( FAILED(hr) )
throw "(CreateAndAddTextNode)Unable to create attribute";
return hr;
}
HRESULT CXMLParser::AddTextNode( PCWSTR wszText, MSXML::IXMLDOMNode *pParent )
{
pParent->text = wszText;
return S_OK;
}
HRESULT CXMLParser::CreateAndAddCDATANode( PCWSTR wszCDATA, MSXML::IXMLDOMNode *pParent )
{
HRESULT hr = S_OK;
//pParent->appendChild(spXMLDOM->createCDATASection(wszCDATA));
MSXML::IXMLDOMCDATASectionPtr spCDATA = NULL;
spCDATA = spXMLDOM->createCDATASection(wszCDATA);
if ( !spCDATA )
throw "(CreateAndAddCDATANode)Unable to create CDATA XML node";
hr = AppendChildToParent(spCDATA, pParent);
if ( FAILED(hr) )
throw "(CreateAndAddCDATANode)Unable to create CDATA XML node";
return hr;
}
HRESULT CXMLParser::CreateDocumentFragment( MSXML::IXMLDOMDocumentFragmentPtr &docFrag )
{
HRESULT hr = S_OK;
docFrag = spXMLDOM->createDocumentFragment();
if ( !docFrag )
throw "(CreateDocumentFragment)Unable to create XML document fragment";
return hr;
} |
|
Вот так вызываю:
C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| MSXML::IXMLDOMElementPtr spRoot;
MSXML::IXMLDOMElementPtr spNode;
MSXML::IXMLDOMElementPtr spSubNode;
MSXML::IXMLDOMDocumentFragmentPtr spDF;
_bstr_t bstrXML;
CXMLParser *XMLParser = new CXMLParser;
XMLParser->CreateAndAddPINode( L"xml", L"version='1.0'" );
XMLParser->CreateAndAddCommentNode( L"sample xml file created using XML DOM object." );
XMLParser->GetXML( bstrXML );
XMLParser->CreateElement( L"root", spRoot );
XMLParser->CreateAndAddAttributeNode( L"created", L"using DOM", spRoot );
XMLParser->AppendRoot( spRoot );
XMLParser->CreateAndAddElementNode( L"node1", L"\n\t", spRoot, &spNode );
// Не работает добавление текста методом
// XMLParser->CreateAndAddTextNode( L"some character data", spNode );
spNode.Release();
XMLParser->CreateAndAddElementNode( L"node2", L"\n\t", spRoot, &spNode );
// Не работает добавление текста методом
// XMLParser->CreateAndAddCDATANode( L"<some mark-up text>", spNode );
spNode.Release();
// Вылетает на методе CXMLParser::CreateElement
// на строке
// spElement = spXMLDOM->createElement( wsxName );
XMLParser->CreateAndAddElementNode( L"node3", L"\n\t", spRoot, &spNode );
delete XMLParser; |
|
0
|