3

C++ で XML DOM ドキュメントを作成しています。私の問題は次のとおりです。ドキュメント内の要素から XPATH クエリを実行すると、別の要素が返されることがわかっています。elementPtr->selectSingleNode 呼び出しは、IXMLDOMNode を返します。このノードの属性にアクセスするにはどうすればよいですか?

私の一部は、ノードを要素にダウンキャストしたいと考えていますが、キャストを機能させることができませんでした。

私は試した

MSXML2::IXMLDOMElementPtr pParentElement;
pParentNode->QueryInterface(__uuidof(MSXML2::IXMLDOMElement), 
                            (void**) &pParentElement);

次の実行時エラーが発生します。

0x0057cc58 _com_error::`scalar deleting destructor'(unsigned int)

私が試した他のルートは、ノードを使用することでした:

MSXML2::IXMLDOMNodePtr pParentNode = 
    pParameterElement->selectSingleNode("parent");
MSXML2::IXMLDOMNamedNodeMap* pParentAttributes;
pParentNode->get_attributes(&pParentAttributes);

MSXML2::IXMLDOMNodePtr pCategoryNameNode = 
    pParentAttributes->getNamedItem("Category");
VARIANT value;
pCategoryNameNode->get_nodeValue(&value);
CString categoryName = value;

これは「parentNode->get_attributes()」で失敗します。

何かが足りないようです。API はそれほど使いにくいものであってはなりません。

- 編集 -

私が見逃していたのは、selectSingleNode 呼び出しが失敗し、NULL ポインターが残っていたことです。その上で QueryInterface を呼び出すことも、その上で get_attributes を呼び出すこともできません:P

間違った質問をしたことに気付くのに役立った回答ではなく、質問に適合する回答を選択しました。

4

3 に答える 3

6

あなたの書いたものに間違いは見当たりません。

smart com ポインターは、可能であれば変換に役立ちます。クエリ インターフェイスを自分で記述する必要はありません。

MSXML2::IXMLDOMNodePtr pParentNode = pParameterElement->selectSingleNode("parent");
MSXML2::IXMLDOMElementPtr pParentElement( pParentNode );

私の意見では、Ptr 型を使用するのは少し面倒ですが、MSXML インターフェイスでは Ptr 型が好まれます。ATL を使用した同等の例を次に示します。

CComPtr<IXMLDOMNode> node = ...;
CComQIPtr<IXMLDOMElement> elementNode( node );

if( elementNode ) { 
// it was an element!
} else { 
// it's something else try again? 
}

他の試みは次のようになります...

CComPtr<IXMLDOMNamedNodeMap> attributes;
node->get_attributes( &attributes );
if( attributes ) {
  _bstr_t name( L"category" );
  attributes->getNamedItem(name);
}

そして、それは COM です。C++ で使用するのは常に困難です :(

于 2008-11-14T03:58:47.923 に答える
1

IXMLDOMNode から IXMLDOMElement へのダウンキャストをどのように試みましたか? これは COM オブジェクトであるため、C++ キャストをそのまま使用することはできません。QueryInterface() を使用する必要があります。


あなたの QueryInterface() コードを見ると、いくつかの考えがあります:

  • pParentNode は間違いなく null ではありませんか? あなたが得たものを考えると、これが問題だとは思いませんが、チェックする価値はあります。
  • QueryInterface() 呼び出しはまったく正しくないと思います。返されたインターフェイスで AddRef() を何らかの方法で呼び出す必要がありますが、コードはそうしません。別のポスターが指摘したように、_com_ptr_t<> を取得してこれを行うことができます。

    MSXML2::IXMLDOMElementPtr pParentElement(pParentNode);
    

これを行うことで、おそらく AddRef()/Release() の不一致が原因である「スカラー削除デストラクタ」エラーが停止することを願っています。

とにかく、上記を試して、pParentElement が null かどうかを確認してください。そうである場合、次にお勧めするのは、pParentNode で get_nodeType() を呼び出して、実際のノードの種類を確認することです。これにより、XPath が期待どおりに返されていないかどうかの手がかりが得られる場合があります。

于 2008-11-13T22:06:22.220 に答える