You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-users@xalan.apache.org by Charles Nicholson <cn...@liquidnet.com> on 2002/03/07 15:55:21 UTC

RE: removeChild of xalanNode (found by xpath) from parsed xml fil e throw XalanDomExeption

Hello-
 
We serialize DOM documents to memory buffers like this:
 
----------------------------------------------------------------------------
-------------------------------------------------
XalanDocument *document;  // assume below that it's initialized and valid
stringstream target_stream; // this is the output stream
 
XalanStdOutputStream output_stream(target_stream);
XalanOutputStreamPrintWriter writer(output_stream);
FormatterToXML formatter(writer);
FormatterTreeWalker tree_walker(formatter);
tree_walker.traverse(document);
 
// at this point, target_stream contains the serialized DOM Document.
// access the raw 'char *' type with target_stream.str().c_str().
----------------------------------------------------------------------------
---------------------------------------------------
 
and it seems to work pretty well.  One problem we have is that this method
does not allow partial serialization (i.e. you can't serialize just a
subtree, it looks to us like an issue in the implementation of
FormatterTreeWalker::traverse, but we could simply be using it wrong.  Has
anyone else encountered this?
 
Regards,
-Charles Nicholson
 
-----Original Message-----
From: Tankel, Ifat [mailto:Ifat_Tankel@icomverse.com]
Sent: Thursday, March 07, 2002 8:27 AM
To: xalan-c-users@xml.apache.org
Subject: RE: removeChild of xalanNode (found by xpath) from parsed xml fil e
throw XalanDomExeption



Hi 
I succeeded in creating the updated XalanDocument and to serialize it to
cout. 

I order to serialize it to cout I did: 
   { 
        XalanStdOutputStream                theStream(cout); 
        XalanOutputStreamPrinterWriter   thePrinterWriter(theStream); 

        FormatterToXML          theFormatter(thePrinterWriter)' 
        FormatterTreeWalker   theWalker(theFormatter); 
        
        theForamtter.startDocument(); 
        { 
        // here I created NodeRefList using the evaluator and scanned here
items 
        // and on each Node I did 
        theWalker.traverseSubtree(theNode); 
        } 
        theFormatter.endDocument(); 
  } 

Now I can see the update Document on cout. 

I want to write it to a string buffer (char * buffer ) in order to be able
to send it to other application. 

I thought that instead of XalanStdOutputStream I will be able to use other
XalanOutputStream derived class 
but no one of them seemed to me to be the right one. 
I tried to replace it with the XalanFileOutputStream but I recieved an
exeption 

so 
How can I do that ? 

regards 
Ifat 

p.s 
about the XSLT I need to check it with some people here 


-----Original Message----- 
From: David N Bertoni/Cambridge/IBM [ mailto:david_n_bertoni@us.ibm.com
<ma...@us.ibm.com> ] 
Sent: Tuesday, March 05, 2002 9:50 PM 
To: xalan-c-users@xml.apache.org 
Subject: RE: removeChild of xalanNode (found by xpath) from parsed xml file
throw XalanDomExeption 



Hi Ifat, 

I would encourage you to consider writing most of your application using 
XSLT.  That could be more efficient, both in terms of coding time and 
execution time, than using DOM, using XPath to find nodes, manipulating the 
DOM, then serializing back to XML.  For some of your proposed 
functionality, you'll likely need custom coding to glue everything 
together, but if I were writing this application, I would push as much onto 
XSLT as possible.  For example, removing certain nodes from an XML document 
is trivial in XSLT.  You can also generate the text for SQL commands to do 
the database updates.  The result document could be generated using a 
stylesheet with the result of the SQL commands passed in as a top-level 
parameter. 

Since XSLT is a general-purpose transformation language for XML, as long as 
you can specify what you want to do as "rules," you can write a stylesheet 
instead of application code.  Of course, you'll need to learn XSLT, but 
that's standard, while all of the Xerces and Xalan private APIs are not. 

As far as the specific problems you're having with your code -- it's next 
to impossible to help out unless you can provide a small, _concise_ sample 
that demonstrates the problem.  There's simply too much information in your 
posting to figure out what the problem is. 

If I get some time, I will work on a sample application using Xerces and 
Xalan to do what your trying to do.  But I urge you to consider using XSLT, 
as it will save you lots of effort. 

Dave 



 

                      "Tankel, Ifat"

                      <Ifat_Tankel@ico         To:
xalan-c-users@xml.apache.org                          
                      mverse.com>              cc:      (bcc: David N
Bertoni/Cambridge/IBM)                  
                                               Subject: RE: removeChild of
xalanNode (found by xpath) from    
                      03/05/2002 08:26         parsed xml fil e throw
XalanDomExeption                        
                      AM

 

 




Hi, Dave 
My Application need to: 
- be able to receive XML buffer (this is the request) 
- read it and understand what kind of action/s need to be done 
- send back my XML buffer answer (this is the response) 

Example for some actions that need to be done: 
1. Read XML file from the disk to memory ( do not change the file on disk) 
, 
make  some manipulation on XML file in memory (like removing nodes , 
replacing values ...), 
    create XML buffer which include the XML memory file as its data node 
(this is the answer buffer that will be sent). 
2. Read some data in the XML buffer received , create command that will be 
send to a DB Server to add/modify the right DB table with the right data. 
    create XML buffer which will tell if action succeeded or failed. (this 
is the answer buffer that will be sent). 
3. Read some data in the XML buffer received , create command that will be 
send to a DB Server to retrieve data from DB, convert the DB answer to XML 
    , create XML buffer which include the converted DB answer as its data 
node. (this is the answer buffer that will be sent). 
 and there are more 

I thought to create Request and Response class each one of them will hold a 
member of type myDom. 
and I though to create myDom class. 
where as myDom class will hold in it (as a data member ) a DomDocument and 
method like: 
             init will enable to initiate this member with the right data 
(init 
from file or buffer that will be received or a other myDom object ) 
             getValue will enable to search a value from this member 
according to 
the Xpath provided. 
             addDomToDom will enable to add a node form other myDom object 
to 
this member. Two xpath provided one to identify the node to be added , 
second to set the              position where to insert the new node to. 
             and more methods.... 
I though to use the xercess c++ but since I need the Xpath I understood I 
will have to use the Xalan c++ (am I right?) 
I downloaded the Xalan and I am trying to create the myDom class  and use 
it 
from a simple main. 
myDom class members are: static DOMParser * _domParser; static 
XercesDOMSupport * _domSupport,static XercesParserLiaison * _parserLiaison; 

                                           static XPathEvaluator * 
evaluator; 
XalanDocument * _xalanDocument; DOM_Document * _domDocument  ..... 

right now this main does: 
create a myDom instance; 
             call myDom::init(from file) to initate this instance members 
             call myDom::removeNode(of xpath) to manipulate this instance. 

the constructor create the data members needed (using new ) 
and init method initiate the _xalanDocument and the _domDocument (as in the 
usage pattern) 
removeNode method create NodeRefList using the evaluator->selectNodeList 
remove the XercesElementNodes nodes found 
             then I create a _new_ NodeRefList using the evaluator and use 
the 
same steps as in the serialize example to print the _xalanDocument. 
             and as I said although this is a new NodeRefList created it 
still 
include the nodes removed - I did not anderstood way? 

as for the usage pattern that describes how to parse a document using 
Xerces 
then wrap the Xerces DOM is yours 
I did use it but only the first 2 parts : I parsed the file with the 
DOMParser and then wrap it with the XercesParserLiaison 

If I understood you I need to call 
xercesParserLiaison::destroyDocument(_xalanDocument) and then create it 
again by calling xercesParserLiaison::createDocument(_domDocument) which 
means _xalanDocument (which is a XalanDocumant *) can not be a member in 
myDom class. 
I tried it and I sow that the nodes where removed 
but way when I check the parent of the node removed with hasChildNodes() it 
has , and if I create a XalanNodeList of this parent node it lengths is 2 ? 

Is there any place where I can see the class diagram of the Xalan? 
I have just finished a short course named "advanced OOP using Patterns in 
C++" it will help me learn the Xalan better. 
regards 
Ifat 




-----Original Message----- 
From: David N Bertoni/Cambridge/IBM [ mailto:david_n_bertoni@us.ibm.com
<ma...@us.ibm.com> ] 
Sent: Monday, March 04, 2002 8:51 PM 
To: xalan-c-users@xml.apache.org 
Subject: RE: removeChild of xalanNode (found by xpath) from parsed xml file 
throw XalanDomExeption 



When you modify the Xerces DOM, you must rebuild the Xalan nodes that 
bridge their DOM to ours.  There is a usage pattern that describes how to 
parse a document using Xerces, then wrap the Xerces DOM in ours.  You need 
to destroy the original wrapper, then create a new one to see the changes. 
Of course, if some of the nodes in your node list were the ones you 
removed, then of course you'll see them in the output.  Removing the nodes 
from the document does not destroy them, nor does it remove them from the 
list. 

There are also many previous discussions in the mail archives on this 
topic.  Make sure you search the Xalan Developer list, since that's been 
around much longer than the Xalan-C user list: 

   http://marc.theaimsgroup.com/?l=xalan-dev
<http://marc.theaimsgroup.com/?l=xalan-dev&r=1&w=2> &r=1&w=2 

Here's a link to the usage pattern for the DOM: 

   http://xml.apache.org/xalan-c/usagepatterns.html#dom
<http://xml.apache.org/xalan-c/usagepatterns.html#dom>  

You can also serialize the Xerces DOM_Document instance, instead of 
rebuilding the bridge and running our serializer.  There's been much talk 
about a serializer on the Xerces-C mailing list.  You might want to 
subscribe, or search the archives. 

I'm still not clear on what your application is trying to do.  It would 
better for you to describe your _entire_ application model, instead of just 
portions of it.  Otherwise, it's pretty difficult to figure out the best 
way for you to proceed. 

Dave 





                      "Tankel, Ifat" 

                      <Ifat_Tankel@ico         To: 
xalan-c-users@xml.apache.org 
                      mverse.com>              cc:      (bcc: David N 
Bertoni/Cambridge/IBM) 
                                               Subject: RE: removeChild of 
xalanNode (found by xpath) from 
                      03/04/2002 05:09         parsed xml fil e throw 
XalanDomExeption 
                      AM 








Hi, Dave 
I replaced the XalanSourceTreePraserLiaison with the XercesParserLiason and 
then I do succeeded in deleting the Node. 

Now I wanted to see that the XalanDocument * returned by the 
XercesParserLiaison::createDocument  was update (the nodes where removed ) 
so I did the same as in the serialize example 
             I created XalanStdOutputStream 
,XalanOutputStreamPrinterWriter, 
FormatterToXML, and FormaterTreeWalker 
             I called FormatterToXML::startDocument 
             I created nodeList using the evaluator 
             I used the FormatterTreeWalker::traverseSubtree 
             and Finally I I called FormatterToXML::endDocument 

What amazed me was that I saw the Nodes that I removed already on the 
screen? 
then I tried to remove the same Node that were already removed again and I 
got an exception that they do not exist. 
so what's going on? 
I thought that may be the nodes are only marked as been deleted am I right? 

I need to send the updated document to another application as a stream 
buffer Where can I find an example for that? 
I scanned the archive and I did not found something that can help me. 

Regards 
Ifat 




-----Original Message----- 
From: David N Bertoni/Cambridge/IBM [ mailto:david_n_bertoni@us.ibm.com
<ma...@us.ibm.com> ] 
Sent: Tuesday, February 26, 2002 11:54 PM 
To: xalan-c-users@xml.apache.org 
Subject: Re: removeChild of xalanNode (found by xpath) from parsed xml file 
throw XalanDomExeption 



Ifat, 

Please try to limit the size of your post to something more reasonable. 
This is quite a bit of code, and a smaller example is much easer to 
understand. 

> void myDom::removeNode(string xpath){ 
>   cout <<"-------------removeNode start " <<endl; 
>   try{ 
>     XalanNode * xpathNode=this->getNode(_evaluatorI,xpath); 
>     cout << "parent node type=" << 
> xpathNode->getParentNode()->getNodeType()<< endl; 
>     cout << "parent node name=" << 
> xpathNode->getParentNode()->getNodeName()<< endl; 
>     (xpathNode->getParentNode())->removeChild(xpathNode); 
>     cout << "remove child finished" <<endl; 
>     cout <<"-------------removeNode finished " <<endl; 
>   } 
>   catch (const XalanDOMException & e) { 
>     cout << "XalanDomExeption was thrown code=" << e.getExceptionCode() 
> <<endl 
>             << e.getMessage().c_str() <<endl 
>             << e.getType().c_str() <<endl 
>             << e.getLineNumber <<endl 
>             << e.getColumnNumber() <<endl; 
>     throw; 
>   } 
>   catch(...){ 
>     cout << "Exeption was thrown" <<endl; 
>     throw; 
>   } 
> } 

The tree that Xalan builds is not mutable.  If you check the error code in 
the XalanDOMException instance, you'll see that it's 
NO_MODIFICATION_ALLOWED_ERR.  If you want to do this sort of thing, you'll 
need to use the Xerces DOM and our wrapper around their DOM.  There is more 
information in the documentation and you'll find lots of discussion about 
this in the mail archives. 

>   XalanDocument * _xalanDocument;//not been deleted at the distructor 
since 
> ParserLiaison owns it 
>  XalanNode * _contextNode;//not been deleted at the distructor since 
delete 
> cause segmentation fault-way? 

Because the document owns it, and it's destroyed when the document is 
destroyed. 

... 

> hope some one can help 
> regards 
> Ifat Tankel 

Dave