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.