i'm currently working with xerces 3.1 in visual studio 2010.
I've written this (very simple) piece of code:
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();
The problem is, the adoptNode(...) method will always return a null-pointer no matter what. I really don't understand what's going on here, please help me!
PS: I know i could use the importNode(...) method and remove and release the old node from the old document, but i was hoping there was a way to fix my problem with adoptNode(...)!
The xerces api states the following for adoptNode(DOMNode* source):
Changes the ownerDocument of a node, its children, as well as the attached attribute nodes if there are any.
After some research i took a look at the implementation of adoptNode in xerces 3.1 and the sad truth is that it's not possible. Quoting the sourcecode:
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;
}
EDIT:
There is a workaround for this method but it requires some knowledge of the DOM-Implementation (especially when using UserData). You can import the node with importNode(...) and delete the other node out of the old document.
The old nodes should be released in order to not waste memory!
If you've got userdata attached to the old nodes, the new document has to have some UserDataHandler which adopts the userdata from the old node to the new node!
Please note that possible references on the old nodes do not point onto the new nodes now. They'll have to be changed manually (or with some UserDataHandler workaround)
Related
In short, while I tried to modify AST, the eclipse cdt gives me org.eclipse.cdt.internal.formatter.AbortFormatting, Code sample:
for ( IASTNode node : nodes) {
rewriter.replace(node, node.copy(), null);
}
Change change = rewriter.rewriteAST();
change = change.perform(new NullProgressMonitor());
this simple code just replace a node with a same copy of it, just for sake of testing, some nodes replaced successuflly and other gives me this exception
org.eclipse.cdt.internal.formatter.AbortFormatting: [1783/54] Unexpected token type, expecting:23, actual:Token type=1 image =IdleTime offset=89705
I have been struggling for a while to know the reason and how to solve it but with no luck
I'm exploring ways to alter the AST of a C/C++ code (e.g., rename a node, add a new variable) and apply these changes to the source file.
I did a lot of reading here in SO and in Eclipse forums. However I didn't find a minimal working example.
It seems that the correct way to make changes in an AST is by using the ASTRewrite class.
A similar question was asked in SO a few months ago, but it is still pending.
Here is where I'm stuck at the moment:
//get the factory
INodeFactory nodeFactory = myAST.getASTNodeFactory();
//create a new function declarator
IASTNode n = nodeFactory.newFunctionDeclarator(nodeFactory.newName("testMe"));
//get the rewriter
ASTRewrite rewriter = ASTRewrite.create(mainAST);
//replace node with n, node is not null
rewriter.replace(node, n, null);
//make the changes
Change c = rewriter.rewriteAST();
c.perform(new NullProgressMonitor());
When I run this code snippet, I get a
java.lang.NoClassDefFoundError: org/eclipse/ltk/core/refactoring/Change
Any hints are appreciated.
I need to create a node at run time, with similar parameters as the other nodes. For that I am creating a dynamic node in ned file as:-
host_send4: meshnode {
parameters:
#dynamic;
#display("p=1000,535;r=200,green;i=device/smallrouter");
}
To implement this node in C++ file, I add this code:-
cModuleType *meshnode1 = cModuleType::get("inet.networklayer.manetrouting.PASER.meshnode");
cModule *mod = meshnode1->createScheduleInit("host_send4", this);
cDisplayString& dispstr = mod->getDisplayString();
dispstr.parse("p=1000,535;r=200,green;i=device/smallrouter");
mod->buildInside();
mod->scheduleStart(simTime()+5*beaconInterval);
But I am not able to build it properly. I think I am in need of any example on this. Can anybody help me to point out an example in INETMANET of mixim or any other oment framework, where this functionality is already implemented.
Thanks for your help.
I have also though of creating a node statically, which would appear in simulation at later point of time. Is it possible and is there any example with runtime appearance and disappearance of node in INET or other OMNET framework.
The OMNeT++ User Manual has a section dedicated to this. According to this you don't need buildInside() and scheduleStart() when using createScheduleInit().
An example how this is performed can be seen in the Veins framework - more precisely in the TraCIScenarioManager. The important lines for you are probably:
cModule* parentmod = getParentModule();
if (!parentmod) error("Parent Module not found");
cModuleType* nodeType = cModuleType::get(type.c_str());
if (!nodeType) error("Module Type \"%s\" not found", type.c_str());
cModule* mod = nodeType->create(name.c_str(), parentmod, nodeVectorIndex, nodeVectorIndex);
mod->finalizeParameters();
mod->getDisplayString().parse(displayString.c_str());
mod->buildInside();
mod->scheduleStart(simTime() + updateInterval);
I found a memory leak in my application using libxml++ due to an XML document where I replace the root node. I took good care for removing any child nodes, but using the xmlpp::Document interface I find no way to replace the root node.
This is a sample of the offending code:
xmlpp::Document Doc;
Doc.create_root_node("root");
// Populate the document
// [...]
void ReplaceRootNode(const xmlpp::Element* NewRootNode)
{
// Remove all root node children
xmlpp::Element* RootNode = Doc.get_root_node();
const xmlpp::Node::NodeList Children = RootNode->get_children();
xmlpp::Node::NodeList::const_iterator itChild = Children.begin();
while (itChild != Children.end()) {
RootNode->remove_child(*itChild++);
}
// Replace root node
Doc.create_root_node_by_import(NewRootNode); // Leak: memory for previous root node is not freed
}
The solution I came up with so far is to edit the document's root node to change it's name and attributes but. Is there a simpler way to avoid this leak which does not involve edition of previous root node's name and attributes?
I work around this by setting the document to an empty Document object (Doc = xmlpp:Document()) before calling create_root_node_by_import instead of removing the root's child nodes explicitly. This appears to cause the previous contents of Doc to be freed.
I first encountered this problem several years ago, and it still does not appear to be fixed in recent versions of libxml++. Surely they must be aware of it. Could this case somehow be using create_root_node_by_import in an unintended fashion? I would not have thought so, but OTOH this seems too important not to fix.
I am using Xerces-c in my project, and would like to create a single DOMElement without having to create a whole new DOMDocument. Is such a thing possible?
I haven't seen a way. AFAIK the DOMDocument acts as the "memory pool" and all elements are created in this pool. In the Xerces docs we see:
Objects created by DOMDocument::createXXXX
Users can call the release() function to indicate the release of any orphaned nodes. When an orphaned Node is released, its associated children will also be released. Access to a released Node will lead to unexpected behaviour. These orphaned Nodes will eventually be released, if not already done so, when its owner document is released
I've worked around this situation by keeping a scratch pad DOMDocument around and using it to create fragments or orphan nodes and adopting them into their destination documents when I'm ready. E.g.
// Create a fragment holding two sibling elements. The first element also has a child.
DOMDocumentFragment* frag = scratchDom->createDocumentFragment();
DOMNode* e1 = frag->appendChild( frag->getOwnerDocument()->createElement("e1") );
e1->appendChild( e1->getOwnerDocument()->createElement("e1-1") );
DOMNode* e2 = frag->appendChild( frag->getOwnerDocument()->createElement("e2") );
...
// Paste the contents of the fragment into a "parent" node from another document
DOMNode* parentFromOtherDom = ...;
parentFromOtherDom->appendChild( parentFromOtherDom->getOwnerDocument()->adopt(frag) );
scratchDom->removeChild(frag);