MSXML DOM Parser
-
HI,
hat hier jemand fundiertes Wissen über den MSXML(msxml4) DOM Parser?
Ich hab ein paar sehr spezielle Fragen, nur leider hab ich nicht mal bei google ein paar ansätze gefunden.
MFG
DOM
-
Um etwas genauer zu werden:
Ich möchte vom ersten Knoten der Datei "Beispiel.xml" den Inhalt jedes einzelnen Elements ausgeben.
<root>
<ebene>
<bction>
<action1>text_1</action1>
<action2>text_2</action2>
<action3>text_3</action3>
</bction>
</ebene>
</root>Wenn ich das mache, bekomme ich alles auf einmal.
for ( pNode = xmlMgr.GetFirstChild(); pNode != NULL; pNode = xmlMgr.GetNextSibling(pNode))
{
pNode = xmlMgr.GetFirstChild(pElem);
strNodeName = xmlMgr.GetText(pNode);
::MessageBox(NULL , strNodeName.c_str() , "Auslesen XML" , MB_OK);
}Die MessageBox gibt mir
text_1 text_2 text_3
aus.
Ich möchte aber text_1 im nächten Schleifendurchgang text_2 usw.
Brauche sowas wie "GetNextElement", leider ist nichts beim DOM Parser was ich dazu nutzen kann. Aber vielleicht hat hier ja jemand ne Idee.
PS: Ich weiß "MessageBox" ist MFC aber ich auch schon vor ner Weile im MFC Forum gepostet und da konnte mir niemand weiterhelfen.
-
try { IXMLDOMDocumentPtr xmlDoc(__uuidof(DOMDocumen)); if(xmlDoc->load(fileName)) { IXMLDOMElementPtr root = xmlDoc->getDocumentElement(); if(root) { IXMLDOMNodeListPtr nodeList = root->selectNodes(L"ebene/bction/action1"); for(int i = 0, len = nodeList->Getlength(); i < len; ++i) { _bstr_t str = nodeList->Getitem(i)->GetnodeTypedValue(); ::MessageBox(0, str, "node value", 0); } } } } catch(const _com_error &err) { //... }
-
Hallo und Danke für deine Antwort.
Leider funktionieren einige Dinge aus deinem Beitrag bei mir nicht. Ich kann z.B.
bei Getlength() nurfor(int i = 0, len = nodeList->get_length(&laenge); i < len; ++i)
get_length mit Parameter aufrufen.
und das
[cpp]nodeList->get_item(i,&m_pCurrent)->GetnodeTypedValue()[/cpp]
will mein Compiler auch nicht haben.
Welche MSXML Version benutzt du? (Ich nutze die msxml4)
MFG
-
Diese Phänomen hat nicht mit der Version von MSXML zu tun sondern mit der Art
wie du es einbindest bzw. verwendest. Die Version mit expliziter Parameterangabe
bei den Properties verwendet die sogenannten RAW-Interfaces. ssm verwendet jedoch
generierte Wrapper-Methoden. Ein wichtiger Unterschied liegt dabei in der Tatsache
das beim ihm auch com-errors geworfen werden, während du die fehler durch
Prügung des HRESULT abfangen musst.
Wenn dir das alles nichts sagt, dann liegt das nicht nur daran das meine Erklärungen
schlecht sind :), sondern auch daran das du einiges Wissen über COM haben solltest.
Wenn nicht hast du bei deinem Problem schlechte Karten.Andernfalls zeig mal
wie du die COM-Anbindung durchführst, d.h. wie sieht deine #import-Anweisung
aus oder machst du alles "zu Fuss" ?mfg JJ
-
Hi,
ich benutze raw interfaces:
#import <msxml4.dll> raw_interfaces_only using namespace MSXML2;
Ich fange dann meine Prüfungen mit HRESULT ab. Hab vor 2 Monaten angefangen mich mit MSXML, COM etc. auseinander zu setzen. Deshalb hab ich halt noch einige Probleme damit.
MFG
-
In diesem Sinne sollte das Beispiel von ssm auch mit RAW-Interfaces only funktionieren.
Wichtig ist halt das Auslesen über TypedValue von den jeweiligen Nodes. Ich hoffe
deine context-sensitive Hilfe funktioniert gut.mfg JJ
-
ssm schrieb:
try { IXMLDOMDocumentPtr xmlDoc(__uuidof(DOMDocumen)); if(xmlDoc->load(fileName)) { IXMLDOMElementPtr root = xmlDoc->getDocumentElement(); if(root) { IXMLDOMNodeListPtr nodeList = root->selectNodes(L"ebene/bction/action1"); for(int i = 0, len = nodeList->Getlength(); i < len; ++i) { _bstr_t str = nodeList->Getitem(i)->GetnodeTypedValue(); ::MessageBox(0, str, "node value", 0); } } } } catch(const _com_error &err) { //... }
Leider funktioniert das nur, wenn die xml so Aufgebaut wäre:
<root>
<ebene>
<bction>
<action1>text_1</action1>
<action1>text_2</action1>
<action1>text_3</action1>
</bction>
</ebene>
</root>d.h. wenn alle Tags gleich heißen würden (action1).
So würde er immer nur den ersten Tag ausgeben.Weiß da jemand weiter?
-
DOM schrieb:
Weiß da jemand weiter?
[cpp]
HRESULT hr;
CComPtr<IXMLDOMDocument> xmlDoc;
hr = xmlDoc.CoCreateInstance(__uuidof(DOMDocument));
ATLASSERT(SUCCEEDED(hr));VARIANT_BOOL b;
hr = xmlDoc->load(CComVariant("fileName.xml"), &b);
if(SUCCEEDED(hr) && b)
{
CComPtr<IXMLDOMNode> actionsElem;
hr = xmlDoc->selectSingleNode(CComBSTR(L"root/ebene/bction"), &actionsElem);
ATLASSERT(SUCCEEDED(hr));if(actionsElem)
{
CComPtr<IXMLDOMNode> child;
hr = actionsElem->get_firstChild(&child);
ATLASSERT(SUCCEEDED(hr));while(child)
{
CComVariant value;
hr = child->get_nodeTypedValue(&value);
ATLASSERT(SUCCEEDED(hr));if(!(value.vt & VT_EMPTY) && (value.vt & VT_BSTR))
{
::MessageBox(0, CW2CT(value.bstrVal), "node value", 0);
}CComPtr<IXMLDOMNode> nextSubling;
hr = child->get_nextSibling(&nextSubling);
ATLASSERT(SUCCEEDED(hr));child = nextSubling;
}
}
}[/cpp]