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 Jonathan Turkanis <te...@kangaroologic.com> on 2005/07/19 05:22:28 UTC

Use of XPath for document modifiation

Hi,

I'm writing about using XML in C++, and am briefly covering Xerces and Xalan. 
I'd like to show an example of selecting a DOM node using an XPath expression 
and then removing that node from the document. Unfortunately, while I've found 
several ways to use XPath expressions to select a DOM node, they seem to return 
nodes from a read-only view of the document. When I try to do

        node->getParentNode()->removeChild(node)

I get an exception stating that the document is non-modifiable.

Is there a way to do what I'm trying to do using Xalan? If not, what's another 
simple but non-trivial use of Xalan XPath expressions, outside of a stylesheet?

Best Regards,
Jonathan Turkanis

Re: Use of XPath for document modifiation

Posted by ji...@bayesinf.com.
Hi,

some days ago I posed the question on how could I resolve a Xpath
expression using Xerces (XpathEvaluator class if I am not wrong).

Could someone give a little explanation on how it is done?

I am searching everywhere for samples but cannot get one. (Already tried
pathan code)

I am not worried if results are given read-only.

Thanks !

jima



>> I'm writing about using XML in C++, and am briefly covering Xerces and
> Xalan.
>> I'd like to show an example of selecting a DOM node using an XPath
> expression
>> and then removing that node from the document. Unfortunately, while I've
> found
>> several ways to use XPath expressions to select a DOM node, they seem to
> return
>> nodes from a read-only view of the document. When I try to do
>>
>>         node->getParentNode()->removeChild(node)
>>
>> I get an exception stating that the document is non-modifiable.
>
> Yes, the default implementation is read-only, since it's optimized for
> XSLT, which does not allow modification of the source tree.
>
>> Is there a way to do what I'm trying to do using Xalan? If not, what's
> another
>> simple but non-trivial use of Xalan XPath expressions, outside of a
> stylesheet?
>
> This is a pretty common question, and we should probably do a sample to
> illustrate how it's done.  You can search the mailing list archives of
> both xalan-dev and xalan-c-users for "XercesDOMSupport" for more
> information.
>
> The trick is you should use an instance of XercesParserLiaison instead of
> XalanSourceTreeParserLiaison, and an instance of XercesDOMSupport, instead
> of XalanSourceTreeDOMSupport.  Also, you will need to call
> XercesParserLiaison::setBuildWrapperNodes(true) and
> XercesParserLiaison::setBuildMaps(true).  Once you do that, you can call
> XercesParserLiaison::parseXMLStream() and use the returned XalanDocument
> instance as the source tree for evaluating XPath expressions.
>
> To map the resulting XalanNode instance returned from evaluating an XPath
> expression, you first need to recover a pointer to the underlying
> implementation class by calling XercesParserLiaison::
> mapDocumentToWrapper().  The implementation class XercesDocumentWrapper
> has some member functions called mapNode() that will map the XalanNode
> instances to their underlying Xerces DOMNode instances.  You can then
> manipulate the Xerces DOM instance as you wish.  However, once you've
> modified the underlying Xerces DOM instance, the existing Xalan wrapper
> will be invalid, and you cannot use either the wrapper or the underlying
> Xerces DOM instance for another XPath evaluation.  If you want to preserve
> the underlying Xerces DOM implementation, you can create it using the
> standard Xerces-C APIs, then simply wrap it using XercesParserLiaison::
> createDocument(), rather than using XercesParserLiaison::parseXMLStream().
>
> If it seems complicated, it's meant to be.  Much of the XPath and XSLT
> code assumes the underlying source tree will never be modified, so
> providing a way to wrap the Xerces DOM and allow manipulating it is not
> core functionality and can open up some dangerous holes.  Proceed with
> caution...
>
> Dave
>





Re: Use of XPath for document modifiation

Posted by Jonathan Turkanis <te...@kangaroologic.com>.
david_n_bertoni@us.ibm.com wrote:

>>I'd like to show an example of selecting a DOM node using an XPath 
>> expression and then removing that node from the document. 

> The trick is  ....


> If it seems complicated, it's meant to be.  Much of the XPath and XSLT 
> code assumes the underlying source tree will never be modified, so 
> providing a way to wrap the Xerces DOM and allow manipulating it is not 
> core functionality and can open up some dangerous holes.  Proceed with 
> caution...

Thanks for the quick reply.

My intended audience is people who have used XML in other languages and want to 
do the same in C++. I'm definitely going to recommend Xalan for XSLT, but I 
think it's clear from your explanation above that Xalana is not the right tool 
for somone who wants to use XPath to manipulate a DOM document.

Pathan looks pretty good, but it hasn't had any releases in about a year. What 
do you know about it?

> Dave

Jonathan

Re: Use of XPath for document modifiation

Posted by da...@us.ibm.com.
> I'm writing about using XML in C++, and am briefly covering Xerces and 
Xalan. 
> I'd like to show an example of selecting a DOM node using an XPath 
expression 
> and then removing that node from the document. Unfortunately, while I've 
found 
> several ways to use XPath expressions to select a DOM node, they seem to 
return 
> nodes from a read-only view of the document. When I try to do
> 
>         node->getParentNode()->removeChild(node)
> 
> I get an exception stating that the document is non-modifiable.

Yes, the default implementation is read-only, since it's optimized for 
XSLT, which does not allow modification of the source tree.

> Is there a way to do what I'm trying to do using Xalan? If not, what's 
another 
> simple but non-trivial use of Xalan XPath expressions, outside of a 
stylesheet?

This is a pretty common question, and we should probably do a sample to 
illustrate how it's done.  You can search the mailing list archives of 
both xalan-dev and xalan-c-users for "XercesDOMSupport" for more 
information.

The trick is you should use an instance of XercesParserLiaison instead of 
XalanSourceTreeParserLiaison, and an instance of XercesDOMSupport, instead 
of XalanSourceTreeDOMSupport.  Also, you will need to call 
XercesParserLiaison::setBuildWrapperNodes(true) and 
XercesParserLiaison::setBuildMaps(true).  Once you do that, you can call 
XercesParserLiaison::parseXMLStream() and use the returned XalanDocument 
instance as the source tree for evaluating XPath expressions.

To map the resulting XalanNode instance returned from evaluating an XPath 
expression, you first need to recover a pointer to the underlying 
implementation class by calling XercesParserLiaison::
mapDocumentToWrapper().  The implementation class XercesDocumentWrapper 
has some member functions called mapNode() that will map the XalanNode 
instances to their underlying Xerces DOMNode instances.  You can then 
manipulate the Xerces DOM instance as you wish.  However, once you've 
modified the underlying Xerces DOM instance, the existing Xalan wrapper 
will be invalid, and you cannot use either the wrapper or the underlying 
Xerces DOM instance for another XPath evaluation.  If you want to preserve 
the underlying Xerces DOM implementation, you can create it using the 
standard Xerces-C APIs, then simply wrap it using XercesParserLiaison::
createDocument(), rather than using XercesParserLiaison::parseXMLStream().

If it seems complicated, it's meant to be.  Much of the XPath and XSLT 
code assumes the underlying source tree will never be modified, so 
providing a way to wrap the Xerces DOM and allow manipulating it is not 
core functionality and can open up some dangerous holes.  Proceed with 
caution...

Dave