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

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

MSXMLを使ってノードを削除したい。

MSXML3.0で IXMLDOMDocumentPtr pXMLDOMDoc; pXMLDOMDoc.CreateInstance(__uuidof(DOMDocument)); pXMLDOMDoc->put_async(VARIANT_FALSE); pXMLDOMDoc->validateOnParse = FALSE; pXMLDOMDoc->load( _variant_t("XMLドキュメントのパス") ); としてXMLドキュメントを読み込み、属性が一致したノードを削除したいです。 例:xml <root> <category name='1'> <item> 車 </item> </category> <category name='1'> <item> バイク </item> </category> <category name='2'> <item> 自転車 </item> </category> <category name='2'> <item> 徒歩 </item> </category> </root> 上記のxmlからcategoryのname属性が1のものを削除し 下記のように変換したいです。 <root> <category name='2'> <item> 自転車 </item> </category> <category name='2'> <item> 徒歩 </item> </category> </root>

  • yruri
  • お礼率40% (21/52)
  • XML
  • 回答数4
  • ありがとう数5

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

  • ベストアンサー
  • 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

  • [VBA] MSXML2.DOMDocument

    MSXML2.DOMDocument を用いて、xml のデータを取得しています。 相手のサーバーがダウンしていると、 Dim xmlDoc As New MSXML2.DOMDocument xmlDoc.async = False xmlDoc.Load (taisyoURL) ↑ この部分でフリーズしてしまい、それ以降続行できません。 false も返ってくるわけではないのでどうしたらよいのか 困っております。 タイムアウト又は何かしらの方法でエラー処理をさせる ことはできますでしょうか?

  • プログラムについて

    VC++のソースを読みながら、ヘッダーファイルを作っています。 私が入る前に会社にもめごとがあったのか、ソースが一部欠けて状態であります。たまたま、ソースのヘッタが無い状態で、cppファイルからヘッタを書いているのですが。 下記のソースの宣言をどうしたらいいのかわかりません。 クラスで宣言すればいいのかなぁと思ったのですが、簡単な問題かもしれないのですが、頭がこんがらがってしまっていて、ぜひ、お知恵を貸してください。 *************** 1: IXMLDOMDocumentPtr doc("MSXML.DOMDocument" /* __uuidof(DOMDocument) */ ); 2: HRESULT hr; 3: _variant_t vt(file_name); 4: VARIANT_BOOL stat=FALSE; 5: hr = doc->put_async(VARIANT_FALSE); *************** IXMLDOMDocumentPtr これの宣言部分がわかりません。 1行目でIXMLDOMDocumentPtr 型のdocを宣言しながら、文字列をdocに与えています。(これをどう宣言するのかわかりません。) 5行目でput_asyncというメンバを使っているので、IXMLDOMDocumentPtr はクラスかと思ったのですが、正しいでしょうか。 つらつら書いてしまいましたが、よろしくお願いします。

  • LoadCML

    宜しくお願いいたします。 下記のプログラムで、 set Session("ServiceInfo") = CreateObject("MSXML2.DOMDocument.3.0") Session("ServiceInfo").Async = False Session("ServiceInfo").LoadXML "<?xml version=""1.0"" encoding=""Shift_JIS"" ?>" & Session("RoeApi").ReturnXml.xml とやると、encoding属性が削除されてしまいます。 どうにかencoding属性までロードしたいのですが どなたかご教授頂けないでしょうか。

    • ベストアンサー
    • XML
  • MSXML3でerror: 'C2065 IID_IXMLDOMSelection' :定義されていない識別子です。 が出てコンパイルできない。

    #import "C:\Program Files\Common Files\System\ADO\msado15.dll" rename_namespace("MSXML2") rename("EOF", "EndOfFile") #import "msxml3.dll" using namespace MSXML2; というようにMSXML3をimportし以下のようなソースを 書いたのですがコンパイルエラーになってしまいます。 IXMLDOMDocumentPtr pDoc; IXMLDOMNodeListPtr pNodeList; pDoc.CreateInstance(__uuidof(DOMDocument30)); pDoc->put_async(VARIANT_FALSE); pDoc->validateOnParse = FALSE; pDoc->load( _variant_t(XMLファイル) ); pNodeList = pDoc->selectNodes("//rs:data"); IXMLDOMSelection *pIXMLDOMSelection=NULL; pNodeList->QueryInterface(IID_IXMLDOMSelection, (void**)&pIXMLDOMSelection ); ヘッダがないとよく出てくるエラーだと思いMSDNで調べたらmsxml2.hというヘッダがあるようなことが書かれていました。 そこで #include <msxml2.h> というコードを追加したのですが"見つかりません"と言われてしまいます。 http://cvs.sourceforge.net/viewcvs.py/libxml2-pas/dom2/Attic/MSXML3.pas?rev=1.3 上記のサイトに IID_IXMLDOMSelection: TGUID = '{AA634FC7-5888-44A7-A257-3A47150D3A0E}'; という記載がありこれが見つからないのではと思っていますがどうしたらよいのか分かりません。 アドバイスお願いします。

    • ベストアンサー
    • XML
  • 改行がノード?(JAXP)

    xmlのノードについてですが、 <talkset> <name type="first">abc</name> <comment>hello!!</comment> </talkset> というxmlファイルがあった場合に、 JAXPでの、getNodeList()で全てのノードリストを 得ます(mynodelist=root.getNodeList())。 ここで、mynodelist.item(i)として、 上から、ノードを見ていくプログラムを作ったの ですが、 まず、最初にテキストノード(<talkset>の横の改行) 、次に<name>ノードがきて、次にテキストノード( </name>の横の改行?)が取り出されます。 この場合、本来、<name>ノードの後は属性ノードである type、次に、テキストノード(abc)そしてその後に、 改行(テキストノード)が取り出されるべきだと思う のですが、そうなりません(type属性と、abcが、 ノードとして、取り出せない)。 なにか分かる人、お願いします。

    • ベストアンサー
    • XML
  • VBAでMSXML2.DOMDocument を使用したい

    お世話になります。 下記ソースのようにVBAで「MSXML2.DOMDocument」を使用したいと 思うのですが実行すると 「Dim D As MSXML2.DOMDocument」の箇所で 「コンパイルエラー:ユーザ定義型は定義されていません」 とメッセージがでます。 どのようにすれば「MSXML2.DOMDocument」が使えるのでしょうか? 私は、完全な初心者でありました。何も設定せずに、VBAに下記の 文を入力しました。 解決策と、もし、VBAでDOMを使用する初心者サイトがありましたら 教えて頂ければとおもいます。 よろしくお願いします。 VBAソース-------------------------------------------- Dim D As MSXML2.DOMDocument Set D = New MSXML2.DOMDocument D.async = False If D.Load("C:\SAMPLE.XML") Then MsgBox "読み込み成功" Else MsgBox "読み込み失敗" End If

  • XMLへDOMでタグの追加

    次のようなXMLにDOMで、タグを追加しようとしているのですが、 追加される場所が思った所に追加されません。 正常XMLにようにしたいのですが、どうすれば良いでしょうか? --元XML----------------- <root> <item>a</item> <item>b</item> </root> --結果XML----------------- <root> <item>a</item> <item>b</item> <info>xxxx</info> </root> --正常XML----------------- <root> <info>xxxx</info> <item>a</item> <item>b</item> </root> -- プログラム ---------------- MSXML::IXMLDOMDocumentPtr xmlDoc = NULL; MSXML::IXMLDOMNodeListPtr pNodes; MSXML::IXMLDOMNodePtr pNode; MSXML::IXMLDOMElementPtr pElem; xmlDoc.CreateInstance ("Msxml2.DOMDocument"); xmlDoc->load( ファイル名 ); pNodes = xmlDoc->selectNodes(L"/root"); pNode = pNodes->Getitem(0); pElem = xmlDoc->createElement(L"info"); pNode->appendChild( pElem ); 環境:WinXP+IE7+VC6

    • ベストアンサー
    • XML
  • javascriptでXML IEとfireFox

    作成中のホームページで、条件を入力させてその条件に合ったデータ(XMLで管理)を表示する という内容のモノを作ろうとしています。 実際に一通り動く所までは出来たのですが、IEでしか動作せず Firefox等の他ブラウザだと動作しません。 調べてみると、ActiveXObjectが使えないようなのですが どういう方法で実装すると動作するようになるのでしょうか。 よろしくお願いします。 ----------以下ソース一部---------- // ワーク用の XML ドキュメントオブジェクト var objDocWk = new ActiveXObject("Msxml2.DOMDocument.3.0") // 出力用の新しいルートノードを作成 dstNd = objDocWk.createNode(1, "list", "") // XML ドキュメントオブジェクト生成 var objDoc = new ActiveXObject("Msxml2.DOMDocument.3.0") objDoc.async = false objDoc.load("msch.xml") var objRootNode = objDoc.documentElement.childNodes =======================補足======================= 下記のようにやってみたのですが、jsのエラーが起り原因がわからないです。※fireFoxのみIEでは動作確認済 if (window.ActiveXObject) { //for IE // XML ドキュメントオブジェクト生成 var objDoc = new ActiveXObject("Msxml2.DOMDocument.3.0") objDoc.async = false // 曲情報の読込み objDoc.load("msch/msch.xml") // ワーク用の XML ドキュメントオブジェクト var objDocWk = new ActiveXObject("Msxml2.DOMDocument.3.0") } else { //for Firefox // XML ドキュメントオブジェクト生成 var xhttp = new XMLHttpRequest(); xhttp.open("GET", "msch/msch.xml", false); xhttp.send(null); var objDoc = xhttp.responseText; window.alert(objDoc); // ワーク用の XML ドキュメントオブジェクト var xhttp2 = new XMLHttpRequest(); xhttp2.open("GET", "msch/msch.xml", false); xhttp2.send(null); var objDocWk = xhttp2.responseText; window.alert(objDocWk); } // 出力用の新しいルートノードを作成 dstNd = objDocWk.createNode(1, "musiclist", "") // 曲情報のルートノードを取得 var objRootNode = objDoc.documentElement.childNodes エラー内容が objDocWk.createNode is not a function  と objDoc.documentElement is undefined   です。

  • 属性の値に特殊文字が大量にあるとMSXMLで読み込めない

    MSXMLを使って、属性の値に特殊文字(「<」「>」「&」など)が 大量に使われているXMLを読みこもうとすると失敗します。 正常なXMLと認識されないようです。 「Load」を使ってファイルから読み込んだ場合もダメ。 「LoadXML」で文字列から読み込んだ場合もダメ。 以下のようなVBAコードで再現できます。 --------- Dim oDom As New MSXML2.DOMDocument With oDom.appendChild(oDom.createElement("root"))   With .Attributes.setNamedItem(oDom.createAttribute("attr"))     '.nodeValue = String(65533, "<") 'OK     .nodeValue = String(65534, "<") 'NG   End With End With oDom.loadXML oDom.XML '←正しく読み込めない --------- MSXML4でもMSXML6でも同様でした。 これはバグ、それとも仕様なのでしょうか。 探してもそれらしい資料が見つかりません。 どなたかわかる方、教えてください。 補足ですが、 実は同様のXMLファイルをIE6に読ませようとした場合にも、エラー表示されます。 エラーメッセージは「エラーを特定できません」。 FireFoxだとOKのようです。

    • 締切済み
    • XML
  • XMLファイルのattribute値を取得するには?

    ASP内の処理でwebからXMLファイルをLoadし、 そこからattribute値を取得するにはどうすればよいのでしょうか? ちなみにXMLファイル取得は成功しています。 使用スクリプトはVBscriptです。 以下がロードしたXMLファイルの内容です。 <?xml version="1.0" encoding="Shift_JIS" ?> <xml> <AAA width="2.15" <--この2.15と height="4.60" <--この4.60を取得したい /> </xml> 以下が今、途中まで作っているソースです。 <% language = "VBscript" %> <% Dim XmlDoc, objXmlError, objXmlNode Set XmlDoc = CreateObject("MSXML2.DOMDocument") xmlDoc.async = false XmlDoc.setProperty "ServerHTTPRequest", true XmlDoc.load("http://localhost/test.xml") Set objXmlNode = XmlDoc.selectNodes("/root/AAA") ここから先がよくわからない %>

専門家に質問してみよう