Как я могу получить доступ к атрибутам элемента из IXMLDOMNode? - PullRequest
3 голосов
/ 14 ноября 2008

Я создаю документ XML DOM на C ++. Моя проблема заключается в следующем: я выполняю запрос 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

Я выбрал ответ, который соответствует заданному вопросу, а не ответ, который помог мне понять, что я задал неправильный вопрос.

Ответы [ 2 ]

6 голосов
/ 14 ноября 2008

Я не вижу ничего плохого в том, что вы написали.

Интеллектуальные указатели помогут вам конвертировать, если они могут, вам не нужно писать интерфейс запроса самостоятельно.

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 голос
/ 14 ноября 2008

Как вы пытались выполнить переход от IXMLDOMNode к IXMLDOMElement? Вы не можете просто использовать приведение C ++ для этого, так как это COM-объект: вы должны использовать QueryInterface ().


Глядя на ваш код QueryInterface (), некоторые мысли:

  • Действительно ли pParentNode не равен нулю? Я не думаю, что это проблема, учитывая, что вы получаете, но это стоит проверить.
  • Вызов QueryInterface () не совсем верен, я думаю: вы должны вызывать AddRef () тем или иным образом на возвращаемом интерфейсе, а ваш код - нет. Как отметил другой автор, вы можете заставить _com_ptr_t <> сделать это для вас:

    MSXML2::IXMLDOMElementPtr pParentElement(pParentNode);
    

Выполнение этого, я надеюсь, остановит эту ошибку «скалярного удаления деструктора», которая, вероятно, вызвана несовпадением AddRef () / Release ().

В любом случае, попробуйте вышеописанное и посмотрите, является ли pParentElement нулевым или нет. Если это так, то следующее, что я бы предложил, - это вызвать get_nodeType () для pParentNode, чтобы увидеть, какой это на самом деле узел. Это может дать подсказку о том, что XPath не возвращает то, что вы ожидаете.

...