- - PR -
MSXML3.0で2つのDOMドキュメントを結合したいのですがappendChildで落ちます(.Net Frameworkでないです)
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-09-16 16:24
はじめまして koaraと申します。
閲覧ばかりでしたがはじめて書き込みさせて頂きます。 過去スレを見ましたが、importNodeを使った書き込みはあったのですが どうしても解決できませんでした。 xml1の<rs:data>以下をxml2の<rs:data>以下に追加したいのですがうまくいきません。 vc++6.0にてコンパイルは出来るのですが、appendChildをすると実行時エラーで落ちてしまいます。 xml1.xml: <xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema"> <s:Schema id="RowsetSchema"> <s:ElementType name="row" content="eltOnly" rs:CommandTimeout="30"> <s:AttributeType name="MACHINE" rs:number="1" rs:nullable="true" rs:write="true"> <s:datatype dt:type="string" rs:dbtype="str" dt:maxLength="8190"/> </s:AttributeType> <s:AttributeType name="INTIME" rs:number="3" rs:nullable="true" rs:write="true"> <s:datatype dt:type="string" rs:dbtype="str" dt:maxLength="8190"/> </s:AttributeType> <s:extends type="rs:rowbase"/> </s:ElementType> </s:Schema> <rs:data> <z:row MACHINE="APPLE" INTIME="2005/09/09 12:33:11"/> <z:row MACHINE="DELL" INTIME="2005/09/05 11:13:12"/> </rs:data> </xml> xml2.xml: <xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema"> <s:Schema id="RowsetSchema"> <s:ElementType name="row" content="eltOnly" rs:CommandTimeout="30"> <s:AttributeType name="MACHINE" rs:number="1" rs:nullable="true" rs:write="true"> <s:datatype dt:type="string" rs:dbtype="str" dt:maxLength="8190"/> </s:AttributeType> <s:AttributeType name="INTIME" rs:number="3" rs:nullable="true" rs:write="true"> <s:datatype dt:type="string" rs:dbtype="str" dt:maxLength="8190"/> </s:AttributeType> <s:extends type="rs:rowbase"/> </s:ElementType> </s:Schema> <rs:data> <z:row MACHINE="NEC" INTIME="2005/09/09 02:03:01"/> <z:row MACHINE="HP" INTIME="2005/03/09 11:32:31"/> </rs:data> </xml> を結合して <xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema"> <s:Schema id="RowsetSchema"> <s:ElementType name="row" content="eltOnly" rs:CommandTimeout="30"> <s:AttributeType name="MACHINE" rs:number="1" rs:nullable="true" rs:write="true"> <s:datatype dt:type="string" rs:dbtype="str" dt:maxLength="8190"/> </s:AttributeType> <s:AttributeType name="INTIME" rs:number="3" rs:nullable="true" rs:write="true"> <s:datatype dt:type="string" rs:dbtype="str" dt:maxLength="8190"/> </s:AttributeType> <s:extends type="rs:rowbase"/> </s:ElementType> </s:Schema> <rs:data> <z:row MACHINE="APPLE" INTIME="2005/09/09 12:33:11"/> <z:row MACHINE="DELL" INTIME="2005/09/05 11:13:12"/> <z:row MACHINE="NEC" INTIME="2005/09/09 02:03:01"/> <z:row MACHINE="HP" INTIME="2005/03/09 11:32:31"/> </rs:data> </xml> というDOMDocumentを作りたいです。 以下のようなソース(抜粋しました)になります。 source.cpp: #import "C:\\Program Files\\Common Files\\System\\ADO\\msado15.dll" rename_namespace("MSXML2") rename("EOF", "EndOfFile") #import "msxml3.dll" named_guids using namespace MSXML2; ::CoInitialize(NULL); IXMLDOMDocumentPtr pDoc_xml1; IXMLDOMDocumentPtr pDoc_xml2; //xml1.xml読み込み pDoc_xml1.CreateInstance(__uuidof(DOMDocument30)); pDoc_xml1->put_async(VARIANT_FALSE); pDoc_xml1->validateOnParse = FALSE; pDoc_xml1->load( _variant_t("xml1.xml") ); //xml2.xml読み込み pDoc_xml2.CreateInstance(__uuidof(DOMDocument30)); pDoc_xml2->put_async(VARIANT_FALSE); pDoc_xml2->validateOnParse = FALSE; pDoc_xml2->load( _variant_t("xml2.xml") ); IXMLDOMNode *pIXMLDOMNode1 = NULL; IXMLDOMNode *pIXMLDOMNode2 = NULL; //xml1 pIXMLDOMNode1 = pDoc_xml1->selectSingleNode("//z:row"); //xml2 pIXMLDOMNode2 = pDoc_xml2>selectSingleNode("//rs:data"); //xml1+xml2 pIXMLDOMNode2->appendChild(pIXMLDOMNode1); アドバイスお願いします。 [ メッセージ編集済み 編集者: koara 編集日時 2005-09-16 16:26 ] [ メッセージ編集済み 編集者: koara 編集日時 2005-09-16 16:27 ] [ メッセージ編集済み 編集者: koara 編集日時 2005-09-16 16:31 ] [ メッセージ編集済み 編集者: koara 編集日時 2005-09-16 16:32 ] | ||||||||
|
投稿日時: 2005-09-16 17:01
自己レスです。
IXMLDOMElementPtr ElementPtr1; IXMLDOMElementPtr ElementPtr2; //xml1 ElementPtr1 = pDoc_xml1->selectSingleNode("//z:row"); //xml2 ElementPtr2 = pDoc_xml2->selectSingleNode("//rs:data"); //xml1+xml2 ElementPtr2->appendChild(ElementPtr1); pDoc_xml1->save("c:\\xml1.xml"); pDoc_xml2->save("c:\\xml2.xml"); とすることで1つは追加できましたが、複数追加するにはIXMLDOMNodeListPtr を取得してfor文で取り出すしかないのでしょうか? | ||||||||
|
投稿日時: 2005-09-16 17:54
ぱっと思いつく方法は・・・
@documentFragmentを作成 AXML2から追加したい部分のNodeListを作成 B@にAのノードをループでまわしてappendChild CXML1の追加先ノード.appendChild(documentFragmentのClone) めっちゃ走り書きです。 もっといい方法があるかも。 | ||||||||
|
投稿日時: 2005-09-16 18:25
Vacant-Eyes様 レスありがとうございます。
documentFragmentというものの存在を初めて知りました。 自分なりに調べたのですが、普通はnodeをappendChildする場合ひとつずつ しかできないのだけれど、 documentFragmentというものを経由することであたかもひとつのnodeのように appendChildできるというものでしょうか。 そこで、 IXMLDOMDocumentFragmentPtr pFragmentPtr; IXMLDOMNodeListPtr pNodeList; IXMLDOMNode *pNode=NULL; pNodeList = pDoc_xml->selectNodes("//z:row"); for(int i = 0; i < pNodeList->length; i++){ pNode = pNodeList->Getitem(i); pFragmentPtr->appendChild(pNode); } //xml2 IXMLDOMElementPtr ElementPtr; ElementPtr = pDoc_ado->selectSingleNode("//rs:data"); ElementPtr->appendChild(pFragmentPtr); pDoc_xml->save("c:\\xml1.xml"); pDoc_ado->save("c:\\xml2.xml"); としてみたのですが、 pFragmentPtr->appendChild(pNode); で落ちてしまいます。 MessageBox(NULL, pNode->text, NULL, MB_OK); としても参照できないということはうまくノードを取得できてないのでしょうか? | ||||||||
|
投稿日時: 2005-09-16 19:00
IXMLDOMDocumentFragmentPtr pFp;
pFp = pDoc_xml->createDocumentFragment(); IXMLDOMNodeListPtr pNl; IXMLDOMElementPtr pEm; pNl = pDoc_xml->selectNodes("//z:row"); for(int i = 0; i < pNl->length; i++){ pEm = pNl->Getitem(i); pFp->appendChild(pEm); } //xml2 pDoc_ado->selectSingleNode("//rs:data")->appendChild(pFp); sprintf(szPath_Xml, "%s\\result\\result.xml", szPath); pDoc_ado->save(szPath_Xml); 上記のコードで上手くいきました。 ありがとうございました。 | ||||||||
|
投稿日時: 2005-09-16 20:59
うまくいってよかったですね!(^o^)/
| ||||||||
|
投稿日時: 2005-09-20 08:27
ありがとうございます、おかげで解決できました。
本当のところ出来てしまったという感じで IXMLDOMNodeListPtrの要素を一旦 IXMLDOMElementPtrに格納してから IXMLDOMDocumentFragmentPtr にappenChildして.. という流れが冗長な感じがします。 こういうものだと思えればいいのですが、 理屈が分からないとどうも釈然としません。 参考になるWEBページ等ありましたら教えて頂けませんでしょうか? | ||||||||
|
投稿日時: 2005-09-20 13:15
そうですよね。もっとスマートにできてもいいような気がします。
DOMについて解説しておられるページは探すと結構ありますよ。 個人的には(これは書籍ですが)これがお勧めです。 |