Метод xerces_3_1 acceptNode() возвращает NULL
В настоящее время я работаю с Xerces 3.1 в Visual Studio 2010.
Я написал этот (очень простой) кусок кода:
XMLPlatformUtils::Initialize();
DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(L"XML 1.0");
DOMDocument* doc1 = impl->createDocument(L"nsURI", L"abc:root1", 0);
DOMDocument* doc2 = impl->createDocument(0, L"root2", 0);
DOMElement* root1 = doc1->getDocumentElement();
DOMElement* root2 = doc2->getDocumentElement();
DOMElement* el1 = doc1->createElement(L"el1");
root1->appendChild(el1);
DOMNode* tmpNode = doc2->adoptNode(el1); //tmpNode is null after this line
root2->appendChild(tmpNode);
doc1->release();
doc2->release();
xercesc::XMLPlatformUtils::Terminate();
Проблема в том, adoptNode(...)
Метод всегда будет возвращать нулевой указатель, несмотря ни на что. Я действительно не понимаю, что здесь происходит, пожалуйста, помогите мне!
PS: я знаю, что мог бы использовать importNode(...)
метод и удалить и освободить старый узел из старого документа, но я надеялся, что есть способ исправить мою проблему с adoptNode(...)
!
1 ответ
API xerces утверждает следующее для adoptNode(DOMNode* source)
:
Изменяет ownerDocument узла, его дочерних элементов, а также прикрепленных узлов атрибутов, если они есть.
После некоторого исследования я взглянул на реализацию acceptNode в xerces 3.1, и печальная правда в том, что это невозможно. Цитирование исходного кода:
if(sourceNode->getOwnerDocument()!=this)
{
// cannot take ownership of a node created by another document, as it comes from its memory pool
// and would be delete when the original document is deleted
return 0;
}
РЕДАКТИРОВАТЬ:
Для этого метода есть обходной путь, но он требует определенных знаний о реализации DOM (особенно при использовании UserData). Вы можете импортировать узел с importNode(...)
и удалите другой узел из старого документа.
Старые узлы должны быть освобождены, чтобы не тратить память!
Если у вас есть пользовательские данные, прикрепленные к старым узлам, новый документ должен иметь некоторые UserDataHandler
который принимает userdata от старого узла к новому узлу!
Обратите внимание, что возможные ссылки на старые узлы теперь не указывают на новые узлы. Они должны быть изменены вручную (или с некоторым обходным решением UserDataHandler)