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