如何从IXMLDOMNode访问元素属性?

时间:2008-11-13 21:49:20

标签: c++ dom msxml ixmldomelement ixmldomnode

我正在用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

我选择的答案符合我提出的问题,而不是帮助我意识到我提出错误问题的答案。

3 个答案:

答案 0 :(得分: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 ++中总是难以使用:(

答案 1 :(得分:1)

你是如何尝试从IXMLDOMNode向IXMLDOMElement进行向下转换的?你不能只使用C ++强制转换,因为它是一个COM对象:你必须使用QueryInterface()。


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

  • pParentNode肯定不是null吗?鉴于你得到了什么,我认为这不是问题,但值得检查。
  • QueryInterface()调用不太正确,我认为:你必须在返回的接口上以这种或那种方式调用AddRef(),而你的代码则不然。正如另一张海报所说,你可以得到_com_ptr_t&lt;&gt;为你做这件事:

    MSXML2::IXMLDOMElementPtr pParentElement(pParentNode);
    

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

无论如何,尝试上面的内容,看看pParentElement是否为null。如果是,我接下来要建议的是在pParentNode上调用get_nodeType()来查看它实际上是什么类型的节点。这可能会给出一个关于XPath是否没有返回您期望的线索。

答案 2 :(得分:0)

CComPtr 对于 IXMLDOMNamedNodeMap 是必需的,否则会出现异常:

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