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

我看不出你写的有什么问题。

如果可以的话,智能 com 指针将帮助您进行转换,您不必自己编写查询接口。

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

在我看来,使用 Ptr 类型有点痛苦,尽管 MSXML 接口有利于它们。这是一个使用 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 的?你不能只使用 C++ 强制转换,因为它是一个 COM 对象:你必须使用 QueryInterface()。


查看您的 QueryInterface() 代码,一些想法:

  • pParentNode 绝对不为空吗?考虑到您所得到的,我认为这不是问题所在,但值得检查。
  • 我认为 QueryInterface() 调用不太正确:您必须在返回的接口上以一种或另一种方式调用 AddRef() ,而您的代码不会。正如另一张海报指出的那样,您可以让 _com_ptr_t<> 为您执行此操作:

    MSXML2::IXMLDOMElementPtr pParentElement(pParentNode);
    

我希望这样做会阻止可能由 AddRef()/Release() 不匹配引起的“标量删除析构函数”错误。

不管怎样,试试上面的方法,看看 pParentElement 是否为空。如果是,我建议的下一件事是在 pParentNode 上调用 get_nodeType() 以查看它到底是什么类型的节点。这可能会提供关于 XPath 是否没有返回您期望的内容的线索。

于 2008-11-13T22:06:22.220 回答
0

CComPtr是必要的IXMLDOMNamedNodeMap,否则会有一个例外:

IXMLDOMNamedNodeMap不允许抽象类类型的对象

于 2021-05-20T11:31:45.527 回答