プロが教える店舗&オフィスのセキュリティ対策術

開発環境として、Visual C++ 2008 Express Editionを使用しています。
getAttributeを使用して、XMLの属性を取得しようとしているのですが、取得しようとしている属性が存在しない場合VCから、

「test.exe の 0x10266c70 でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x00000000 を読み込み中にアクセス違反が発生しました。」

と表示されます。

何か属性が存在するかどうか確認するような方法は無いものでしょうか?

A 回答 (2件)

現象を再現できる必要最低限のコードとデータファイルを示しましょう


プログラミングスタイルも明記しましょう C++/CLIなのかWindowsSDKなのかとか

IXMLDOMNodeなら get_attributesでIXMLDOMNamedNodeMapを取得
get_NamedItemで取得する際の戻り値が S_FAILEかどうかで判定できます

下記サンプルは MFCを使用しています
  HRESULT hr;
  IXMLDOMDocument* pDoc = NULL;
  IXMLDOMNodeList* pList = NULL;
  IXMLDOMNode* pNode = NULL, *pItem = NULL;
  IXMLDOMNamedNodeMap* pMap = NULL;

  hr = CoCreateInstance( CLSID_DOMDocument, NULL,
    CLSCTX_INPROC_SERVER,IID_IXMLDOMDocument, (void**)&pDoc );
  CComVariant va("Sample.xml"), vb( FALSE );
  pDoc->put_async( vb.boolVal );
  pDoc->load( va, &vb.boolVal );
  va = CComVariant("node");
  pDoc->getElementsByTagName( va.bstrVal, &pList );
  pList->get_item( 0, &pNode );
  pNode->get_attributes( &pMap );
  // nameの代わりに name1の取得を試みる
  va = CComVariant( "name1" );
  hr = pMap->getNamedItem( va.bstrVal, &pItem );
  if ( hr == S_OK ) {
    pItem->get_nodeValue( &va );
  }

--- sample.xml ---
<?xml version="1.0" encoding="utf-8"?>
<myDS>
<node name="sample1" test="abc"></node>
<node name="sample2" test="abc"></node>
</myDS>
    • good
    • 0
この回答へのお礼

すみません詳細を記述します。
プロジェクトは、Win32コンソールアプリケーションで作っています。
#include<stdio.h>
#import "msxml4.dll" named_guids

int main(void){
  int i,temp;
  VARIANT_BOOL hr;

  MSXML2::IXMLDOMDocument2Ptr  pDoc;
  MSXML2::IXMLDOMElementPtr  pRoot,dir;
  MSXML2::IXMLDOMNodeListPtr  nodeptr;

  /////////XMLからデータ呼び出し///////
  CoInitialize(NULL);//COM初期化

  pDoc.CreateInstance( __uuidof(MSXML2::DOMDocument40));
  // 読み込み待ちで文書を読み込む
  pDoc->put_async(VARIANT_FALSE);
  hr = pDoc->load(L"model.xml");
  if (hr != VARIANT_TRUE) {
    printf("正常に読み込めません。構文が間違っているか、ファイルが存在しない可能性があります。\n");
    //MessageBox(_T("正常に読み込めません"), _T("構文エラー"), MB_ICONERROR);
    return 1;
  }
  pRoot=pDoc->documentElement;
  //XPathを使うように設定
  pDoc->setProperty(_bstr_t(L"SelectionLanguage"),variant_t(L"XPath"));

  // タグ名"name"の要素を取得
  MSXML2::IXMLDOMElementPtr pname=pDoc->getElementsByTagName("name")->Getitem(0);
  
  // "name"要素の属性をチェック
  _variant_t varlang=pname->getAttribute("lang");
  wprintf(L"lang: %s\n",varlang.bstrVal);
  getchar();
  return 0;
}

----model.xml----
<?xml version="1.0" encoding="utf-8"?>
<root>
 <name lang="Japanese">test0</name>
 <name>test1</name>
</root>

という感じで、属性を取得しています。
MFCとかはあまりくわしくないので、このソースに組み込めるチェック方法を教えていただけるとありがたいです。
宜しくお願いします。

お礼日時:2009/04/26 17:22

当方の環境では msxml4.dll が無いので


msxml3.dllで調べてみましたが 同様の症状になりませんでした

  // タグ名"name"の要素を取得
  // GetItemを1にして
  // <name>test1</name> を取得
  MSXML2::IXMLDOMElementPtr pname=pDoc->getElementsByTagName("name")->Getitem(1);
  
  // "name"要素の属性をチェック
  // _variant_t() を追加
  _variant_t varlang=pname->getAttribute( _variant_t("lang") );
で GetItem(1)として 実行しましたが
valangには VT_NULLが取得できました
アサーションにはならずにです

データはお示しのmode.xmlです

IXMLDOMDocumentのインスタンス化は
MSXML2::DOMDocument26
MSXML2::DOMDocument30
MSXML2::DOMDocument60
で行いました
MSXML2::DOMDocument40は登録されていないとなってpDocがNULLのままでした

参考になれば幸いです
    • good
    • 0
この回答へのお礼

_variant_tにはvtってのがあるんですね。
varlang.vt==VT_NULLでチェックするように出来ました。
どうも有り難うございました。

お礼日時:2009/04/26 20:52

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!