Hi!

I have the same problem with the document modification: I want to select a node using XPath and then modify this node (remove it, add attributes to it or add a child node). Here is the part of my source:

DOMDocument *doc = 0;
XercesDOMSupport* theDOMSupport;
XercesParserLiaison* theParserLiaison;
XercesDOMWrapperParsedSource* parsedSource;
XPathEvaluator* theEvaluator;
XercesDocumentWrapper* docWrapper;

XalanNode* contextNode;
XalanNode* rootNode;
vector <XalanNode*> results;

void getResults(XalanNode* node, const string& expr)
{
   XObjectPtr theResult;

   try {
       theResult = theEvaluator->evaluate(*theDOMSupport, node,
XalanDOMString(expr.c_str()).c_str(), XalanDocumentPrefixResolver(docWrapper));
   }
   catch (...) {
       cout << "Exception!" << endl;
   }

   assert(theResult.null() == false);

   const NodeRefListBase& contextNodeList = theResult->nodeset();
   int numItems = contextNodeList.getLength();

   results.clear();

   for (int i=0; i<numItems; i++ ) {
       results.push_back(contextNodeList.item(i));
   }
}

void cd(const string& path, int index, string& message)
{
   if (path[0] == '/' && path != "//" )
       getResults(rootNode, path);
   else
       getResults(contextNode, path);

   if (results.size() == 0) {
       cout << "cd(" << index << ") found an empty result set!" << endl;
       return;
   }
   if (index < 0 || index >= results.size()) {
       cout << "cd(" << index << ") index out of reange!" << endl;
       return;
   }

   contextNode = results[index];
}

void mkdir(const std::string& name, bool cdInto, std::string& message)
{
   assert(contextNode != 0);

   try {
       DOMElement* element = (DOMElement*)docWrapper->mapNode(contextNode);
       XMLCh* TagName = XMLString::transcode(name.c_str());
DOMElement* newElement = (DOMElement*)doc->createElementNS(element->getNamespaceURI(), TagName);

       element->appendChild(newElement);
       docWrapper->rebuildWrapper();

       if (cdInto) {
if (contextNode->hasChildNodes() && (contextNode->getLastChild() == 0)) {
               cout << "Unbelievable!" << endl;
               throw;
           }
           contextNode = contextNode->getLastChild();
       }
   }
   catch (XalanDOMException e) {
       int i = e.getExceptionCode();
       std::cout << "mkdir: XalanDOMException: code" << i << "\n";
   }
   catch (...) {
       std::cout << "mkdir: unknown exception\n";
   }

}

void setNodeValue(const string& attrName, const string& value, std::string& message)
{
   assert(contextNode != 0);

   try {
       DOMElement* element = (DOMElement*)docWrapper->mapNode(contextNode);
       if (attrName.length() == 0) {
           element->setTextContent(XMLString::transcode(value.c_str()));
       }
       else {
element->setAttribute(XMLString::transcode(attrName.c_str()),XMLString::transcode(value.c_str()));
       }
       docWrapper->rebuildWrapper();
   }
   catch(DOMException e) {
       std::cout << "setNodeValue: DOMException\n";
   }
   catch (XalanDOMException e) {
       int i = e.getExceptionCode();
       std::cout << "setNodeValue: XalanDOMException: code" << i << "\n";
   }
   catch(...) {
       std::cout << "setNodeValue: unknown exception\n";
   }
}

int main(void) {
   theDOMSupport = new XercesDOMSupport();
   theParserLiaison = new XercesParserLiaison(*theDOMSupport);
   theParserLiaison->setBuildWrapperNodes(true);
   theParserLiaison->setBuildMaps(true);
parsedSource = new XercesDOMWrapperParsedSource(doc, *theParserLiaison, *theDOMSupport); docWrapper = theParserLiaison->mapDocumentToWrapper(parsedSource->getDocument());

   theEvaluator = new XPathEvaluator();

   rootNode = contextNode = docWrapper->getDocumentElement();

   cd("//cms:programSpecific", 0, message);
   mkdir("IO", true, message);

   int i,j;
   string attrs[5] = {"attr1","attr2","attr3","attr4","attr5"};
   for (i=0; i<2; i++ ) {
       mkdir("dir1", false, message);
       mkdir("dir2", false, message);
       mkdir("dir3", true, message);
       for (j=0; j<2; j++)
           setNodeValue(attrs[j],"value1",message);
   }
}

And now comes the most exciting part: the program's outputs:
[EMAIL PROTECTED] test_xalan]$ ./a.out
[EMAIL PROTECTED] test_xalan]$ ./a.out
Unbelievable!
Aborted
[EMAIL PROTECTED] test_xalan]$ ./a.out
[EMAIL PROTECTED] test_xalan]$ ./a.out
[EMAIL PROTECTED] test_xalan]$ ./a.out
Unbelievable!
Aborted
[EMAIL PROTECTED] test_xalan]$ ./a.out
[EMAIL PROTECTED] test_xalan]$ ./a.out
mkdir: XalanDOMException: code4
setNodeValue: XalanDOMException: code4
setNodeValue: XalanDOMException: code4
[EMAIL PROTECTED] test_xalan]$ ./a.out
Unbelievable!
Aborted
[EMAIL PROTECTED] test_xalan]$ ./a.out
mkdir: XalanDOMException: code4
mkdir: XalanDOMException: code4
setNodeValue: XalanDOMException: code4
setNodeValue: XalanDOMException: code4

Same input, same binary executable. Where am I wrong?
This was compiled using the latest xalan from CVS (xml-xalan_20050717042537.tar.gz), though xalan-1.8 gives the same results.

[EMAIL PROTECTED] vay]$ g++ --version
g++ (GCC) 3.2.3 20030502 (Red Hat Linux 3.2.3-52)

[EMAIL PROTECTED] vay]$ uname -a
Linux re 2.4.21-27.0.1.EL #1 Mon Dec 20 18:56:53 EST 2004 i686 i686 i386 GNU/Linux

With best regards,
A.

Reply via email to