• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:MSXMLを使ってノードを削除したい。)

MSXMLを使ってノードを削除する方法

このQ&Aのポイント
  • MSXMLを使用してXMLドキュメントから指定した属性と一致するノードを削除する方法について説明します。
  • サンプルのXMLドキュメントから、categoryのname属性が1のノードを削除し、変換する方法を紹介します。
  • 要約の内容は、MSXMLを使用してXMLドキュメントからノードを削除する方法と、categoryのname属性が1のノードを削除する方法です。

質問者が選んだベストアンサー

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

>removeAllメソッドがありませんでした そんなことはないはずです。 以下のMSのサイトでMSXML3以降で(C/C++で)使えると書いてあります。 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/html/f313fcf1-1ec1-4438-88f5-0f2154d6c2e9.asp 参考URLによると Applies to IXMLDOMSelection と書いてありますから IXMLDOMSelection を使う必要があります。(メンバーにremoveAllがあります) selectNodesからIXMLDOMSelectionをセットするサンプルが以下にあります http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/html/665e4039-40d1-4aa8-9b98-dd7494dd8268.asp

yruri
質問者

お礼

BLUEPIXYさんにはお世話になりっぱなしです。 感謝してます。 BLUEPIXYさんへは無理でも僕の知ってることで助かる人もいると思うので見習ってレスを入れようと思いました。 連結の方はxsl関数のdocument()を使い出来ました。 そこで削除は<xsl:script>でやろうと考え直していたのですが、 どうやら名前空間 http://www.w3.org/TR/WD-xsl が<xsl:output>等と干渉するらしく 削除はやはりDOMを使うしかないと思っていた矢先でした。 MSDNは昨日調べたのですが、XMLまで辿り着いてMSXML4.0以外の所を探していてReferenceを見つけることが出来ませんでした。 MSDNはもう少し入りやすければいいのですが、慣れるしかないのでしょうね(苦笑 早速試してみます!

yruri
質問者

補足

自分ではMSXML3を使用しているつもりでしたが、実は #import "C:\Program Files\Common Files\System\ADO\msado15.dll" rename_namespace("MSXML") rename("EOF", "EndOfFile") #import "msxml.dll" using namespace MSXML; としておりMSXML2.0を使用していたようです。 そこで #import "C:\Program Files\Common Files\System\ADO\msado15.dll" rename_namespace("MSXML2") rename("EOF", "EndOfFile") #import "msxml3.dll" using namespace MSXML2; としたのですが IXMLDOMSelection pXMLDOMSel; と定義すると プロジェクトのパス\ファイル名\ファイル名.cpp((211) : error C2259: 'IXMLDOMSelection' : 抽象クラスあるいは構造体のオブジェクトが宣言されています。 というエラーと プロジェクトのパス\ファイル名\ファイル名.cpp(211) : warning C4259: 'long __stdcall IDispatch::GetTypeInfoCount(unsigned int *)' : 純粋仮想関数は定義されていません。 c:\program files\microsoft visual studio\vc98\include\oaidl.h(2697) : 'GetTypeInfoCount' の宣言を確認してください。 プロジェクトのパス\ファイル名\ファイル名.cpp(211) : warning C4259: 'long __stdcall IDispatch::GetTypeInfo(unsigned int,unsigned long,struct ITypeInfo ** )' : 純粋仮想関数は定義されていません。 c:\program files\microsoft visual studio\vc98\include\oaidl.h(2700) : 'GetTypeInfo' の宣言を確認してください。 プロジェクトのパス\ファイル名\ファイル名.cpp(211) : warning C4259: 'long __stdcall IDispatch::GetIDsOfNames(const struct _GUID &,unsigned short ** ,unsigned int,unsigned long,long *)' : 純粋仮想関数は定義されていません。 c:\program files\microsoft visual studio\vc98\include\oaidl.h(2705) : 'GetIDsOfNames' の宣言を確認してください。 プロジェクトのパス\ファイル名\ファイル名.cpp(211) : warning C4259: 'long __stdcall IDispatch::Invoke(long,const struct _GUID &,unsigned long,unsigned short,struct tagDISPPARAMS *,struct tagVARIANT *,struct tagEXCEPINFO *,unsigned int *)' : 純粋仮想関 数は定義されていません。 または プロジェクトのパス\ファイル名.cpp(211) : warning C4259: 'long __stdcall MSXML2::IXMLDOMNodeList::raw_reset(void)' : 純粋仮想関数は定義されていません。 プロジェクトのパス\ファイル名\debug\msxml3.tlh(588) : 'raw_reset' の宣言を確認してください。 プロジェクトのパス\ファイル名\ファイル名.cpp(211) : warning C4259: 'long __stdcall MSXML2::IXMLDOMNodeList::get__newEnum(struct IUnknown ** )' : 純粋仮想関数は定義されていません。 プロジェクトのパス\ファイル名\debug\msxml3.tlh(589) : 'get__newEnum' の宣言を確認してください。 プロジェクトのパス\ファイル名\ファイル名.cpp(211) : warning C4259: 'long __stdcall MSXML2::IXMLDOMSelection::get_expr(unsigned short ** )' : 純粋仮想関数は定義されていません。 プロジェクトのパス\ファイル名\debug\msxml3.tlh(4151) : 'get_expr' の宣言を確認してください。 という警告が連発してしまいます。 何が原因なのでしょうか?

その他の回答 (3)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

>警告が連発してしまいます。 実際に試していないのでなんですが http://www.utj.co.jp/xml/dev/dom/dxdom1_1.html http://www.utj.co.jp/xml/dev/dom/dxdom2_1.html が参考になるような気がします

yruri
質問者

補足

レスを付ける場所を間違えてしまいました。 ありがとうございます、一応自己解決しました。 IXMLDOMSelection *pIXMLDOMSelection=NULL; と宣言することでエラー、警告ともでなくなりました。 c2259というエラーコードをgoogleで検索すると オーバーライドと純粋関数というキーワードに突き当たりました。 上記の書き方との繋がりがいまいちつかめてないので、 もう少し調べてみたいと思います。 上記のサイト勉強になりました。 defaultではXSLPatternとなっているのですね。 それとIXMLDOMDocument2でないとXPathが使えない ほんと勉強になります。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

こんにちは、ちょっと反則なんですが、 http://okweb.jp/kotaeru.php3?q=1637728 がもう締め切られちゃったので、こっちに書きます。 今日、ウロウロしてたら、原因と対策を思いつきました。 それは… <xsl:text>-</xsl:text> <xsl:text>,</xsl:text> のように、地の部分に書き込むんじゃなくて、xsl:textエレメントを使うということです。 最初のvalue-of以降の地の部分に書き込みがあるので、以降の改行とかタブがそのまま使われるのだと思います。 っていうかもう試してみましたがうまくいきます!

yruri
質問者

お礼

出来ました、こんな親切にして頂けるなんて感激です。 言葉でありがとうございますと伝えたいです。 地の部分に文字が書いてあるのを認識して 改行等が有効になっていたのですね。 タブ、スペース、改行すべて無視してくれるようになりました。 ありがとうございました。

yruri
質問者

補足

上記の件解決しました。 IXMLDOMSelection *pIXMLDOMSelection=NULL; サンプルを真似したら出来ました、調べていくとオーバーライドと純粋仮想関数というキーワードに行き当たりました。 今から勉強してみます。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

setProperty("SelectionLanguage", "XPath"); して selectNodes("//category[@name='1']"); して removeAll(); すればいいです。 * Jscriptでのサンプル var xmlDoc = new ActiveXObject("Msxml2.DOMDocument.3.0"); var selectNodes; xmlDoc.setProperty("SelectionLanguage", "XPath"); xmlDoc.async = false; xmlDoc.load("move.xml"); if (xmlDoc.parseError.errorCode != 0) { var myErr = xmlDoc.parseError; WScript.Echo("error:" + myErr.reason); } else { selectNodes = xmlDoc.selectNodes("//category[@name='1']"); selectNodes.removeAll(); xmlDoc.save("out.xml"); } 色々面倒くさいのでCでのサンプルではないですが、やることはほぼ同じだと思います。

yruri
質問者

お礼

ありがとうございます。 参考にさせて頂き早速やってみます。 せっかく教えて頂いたので、他の方のためにもCで完成させて、ソースを掲載させてから締切りさせて頂きたいと思います。 大変参考になりました。

yruri
質問者

補足

その後C++で試行錯誤したのですが、 selectNodes = xmlDoc.selectNodes("//category[@name='1']"); は出来たのですが、removeAllメソッドがありませんでした ので以下のように変えたのですが駄目でした。 IXMLDOMNodePtr pXmlNode; IXMLDOMNodeListPtr pXmlNodeList; long lNum = 0; pNodeList = pXMLDOMDoc->selectNodes("//category[@name='1']"); pNodeList->get_length(&lNum); for(long lCount= 0; lCount < lNum; lCount++){ pNodeList->get_item(lCount, &pXmlNode); pXMLDOMDoc->removeChild(pXmlNode); } pXMLDOMDoc->save(xmlの保存先のパス); やりたいことは、DB上の在庫データ(正確には少し違うのですが)を毎日XMLドキュメントとして保管し 1昨日分のデータと本日分のデータを結合して1つのXMLドキュメントにします。 1日分のデータは前1日分のデータを持っているので、 結合の際に前1日分のデータにして出力します。 [例] 前日分のデータ(9/11, 9/12) 本日分のデータ(9/12, 9/13) 必要なデータは 前日分のデータ(9/12)+本日分のデータ(9/12, 9/13) を結合します。 結合しておいてXSLで省く(こちらはやった事があります)という様に方向転換しようかと思うのですが、 A: <root> <move> <category name='2'> <item> 自転車 </item> </category> <category name='2'> <item> 徒歩 </item> </category> </move> </root> B: <root> <move> <category name='1'> <item> 車 </item> </category> <category name='1'> <item> バイク </item> </category> </move> </root> を結合するにはどうしたらよいのでしょうか? できればCでの情報が少なくて困ってるので、Cの情報を希望します。

関連するQ&A