Project

Profile

Help

Create a TextImpl node in 9.2 HE

Added by Anonymous over 14 years ago

Legacy ID: #7785922 Legacy Poster: David Lee (daldei)

I've just finished porting xmlsh (www.xmlsh.org) to use Saxon 9.2 HE. It went a lot smoother then I had feared. I was able to get rid of 2 "hacks" because there are now public functions to support them. But one remains which no longer works. I need to create a TextImpl node to use on MutableNodeInfo.replace(). This is a case where i want to replace a element node with text. (NOT replace the element's children with text). The problem is that TextImpl is a protected class and there is no public methods to create it that I can find. Previously I had declared a helper function in the net.sf.saxon.tree package myself that could bypass the security and instantiate a TextImpl. Now that Saxon HE is a signed jar this throws a security violation. My current workaround seems to work but it is definitely a hack, and I suspect under the hood its doing bad things. I'm createing a text node by this code: parent.replaceStringValue(replace); Item item = parent.iterateAxis( net.sf.saxon.om.Axis.CHILD ).next(); then calling parent.replace( new NodeInfo[] { (NodeInfo)item } , true ); This then replaces a node with its child. I'm quite supprised it works and that the child node doesnt become an orphan of some sort. But it works. However I'd like to suggest a cleaner method. That is to either make TextImpl a public class so I can call new on it, or to provide a factory method which creates a text node.


Replies (4)

Please register to reply

RE: Create a TextImpl node in 9.2 HE - Added by Anonymous over 14 years ago

Legacy ID: #7787676 Legacy Poster: Michael Kay (mhkay)

I have some sympathy with this requirement. At the same time, it's important to remember that the methods in MutableNodeInfo were not really designed as a public updating API, they were designed to support the specific needs of the XQuery update facility. Trying to create a usable public API for updating might involve more change than simply unprotecting a couple of constructors. In fact, I don't think that the TextImpl class is designed to handle parentless text nodes, and to achieve what you are trying to achieve, I think one would definitely want a parentless text node. So I think this needs further thought. In the meantime your workaround is as good as anything I can come up with.

RE: Create a TextImpl node in 9.2 HE - Added by Anonymous over 14 years ago

Legacy ID: #7788291 Legacy Poster: Michael Kay (mhkay)

In looking at this, I noticed that the Javadocs for MutableNodeInfo are incorrect: for the insertChildren() method they say that the nodes-to-be-inserted are copied, and the originals will be unmodified. This is not in fact true; the XQuery logic does the copying before calling this method, and the copies will then be modified in situ by the insertChildren() method. The same happens for the replace() method, though in this case the Javadoc comments don't say this explicitly either way. I will improve the documentation. So I think you should mimic the XQuery logic by creating a copy of the node you want to insert before calling the replace() method. The way the XQuery logic does this is rather more complex than the workaround you have shown (because it's designed to work with any kind of node, and with other potential implementations of MutableNodeInfo): it creates a Builder (by calling MutableNodeInfo.newBuilder() on the target node), creates a document node, creates a text node child, then navigates to the text node child, and uses that as the argument of the insert/replace operation.

RE: Create a TextImpl node in 9.2 HE - Added by Anonymous over 14 years ago

Legacy ID: #7788439 Legacy Poster: Michael Kay (mhkay)

I have changed the documentation for MutableNodeInfo and some of its implementations to be much more precise about what is accepted and what the possible side-effects are; I have also changed the insert() and replace() methods for the linked tree to accept new text/comment/PI children nodes using any node implementation - they are copied if necessary. In particular this means you can use the convenience implementation net.sf.saxon.om.Orphan if you want.

RE: Create a TextImpl node in 9.2 HE - Added by Anonymous over 14 years ago

Legacy ID: #7788543 Legacy Poster: David Lee (daldei)

Fantastic, thank you ! I know MutableNodeInfo isnt officially supported as a public API but I really appreciate this. My needs are modest, I'm only using it in one place and so far its working great. (fyi I use it in the 'xed' command in xmlsh). If it wasn't featureful enough then I'd resort to doing a copy pass to make the edits, but as it is, I can match nodes and make minor edits in-situ I actually want to use XQuery for Updates but for an OS project I dont want to require Saxon PE. BTW, VERY Happy with Saxon HE. You did a great job on the hard decision of what features to include and what to exclude. I found the registered extension function works so much cleaner then the Java reflection solution. Very nice to also indicate that a function has side effects. This way I can mark "xmlsh:eval()" as having side effects so it is more deterministic. It took me only about 2 hours to port from Saxon 9.1, I was expecting more work as I did have some deep 'hacks' in place. The big changes were the extension function, and the replacement of the Pull module for StAX with a differently named class that had to be constructured slightly differently. I was able to get rid of a few hacks as well.

    (1-4/4)

    Please register to reply