Page 1 of 1

XPath without a MainDocumentPart

PostPosted: Thu Sep 23, 2010 10:17 am
by desau
I want to run xpath on a node that's been cloned with the XmlUtils.deepCopy method. Is this possible?

Code: Select all
Object clonedObj = XmlUtils.deepCopy(paraNodeObj);


I want to modify content of the nodes that are returned from xpath, then eventually add the cloned nodes back to the document that I'm working on.

Is this possible?

Re: XPath without a MainDocumentPart

PostPosted: Thu Sep 23, 2010 12:49 pm
by jason
desau wrote:I want to run xpath on a node that's been cloned with the XmlUtils.deepCopy method. Is this possible?


Yes, it is possible.

deepCopy works by marshalling to a byte array, then unmarshalling.

Code: Select all
         Marshaller mar = jc.createMarshaller();
         ByteArrayOutputStream bout = new ByteArrayOutputStream(256);
         mar.marshal(elem, bout);

         Unmarshaller unmar = jc.createUnmarshaller();
         elem = unmar.unmarshal(new StreamSource(new ByteArrayInputStream(
               bout.toByteArray())), valueClass);


Looking at the code in MainDocumentPart.unmarshal, which is what makes the XPath stuff possible, you need something like:

Code: Select all
         binder = jc.createBinder();
         jaxbElement =  binder.unmarshal( node );


So you'll need to copy the deepCopy code into a new method, marshall to a node rather than a byte array, and then do binder.unmarshall.

You then have everything you need to invoke XmlUtils.getJAXBNodesViaXPath

Pretty straightforward. The only thing is you want 2 return objects, the clone and the binder.

You could pass a binder into your method, or you could create a new class which will encapsulate your clone and the binder.

Please post your resulting code. Thanks.

desau wrote:I want to modify content of the nodes that are returned from xpath, then eventually add the cloned nodes back to the document that I'm working on. Is this possible?


I think this should "just work". :-)

Re: XPath without a MainDocumentPart

PostPosted: Thu Sep 23, 2010 3:23 pm
by desau
OK - that makes sense.

I've found a workaround, which may not be a good solution -- I'll follow up in a new thread with my main concern there. If that falls out, I'll go back to this method.

Re: XPath without a MainDocumentPart

PostPosted: Wed Apr 20, 2011 3:32 am
by freemink
Hi Jason,

I too would like to search a cloned (deepCopied) element using XmlUtils.getJAXBNodesViaXPath()

I read through this thread and tried to follow your suggestion, but I couldn't get anywhere. Can you give any further advice on how to be able to search a cloned element (in my case a org.docx4j.wml.Tr)

It seems I only need to convert (wrap) the org.docx4j.wml.Tr as a JAXBElement and call
MainDocumentPart.getJAXBNodesViaXPath(java.lang.String, java.lang.Object, boolean)
http://dev.plutext.org/docx4j/javadoc-2 ... ang.String, java.lang.Object, boolean)

But I'm new to this and guess I'm missing something?

Thanks for any help...

Re: XPath without a MainDocumentPart

PostPosted: Thu Apr 21, 2011 1:35 am
by jason
No, you need a binder object, The method you mentioned does:
Code: Select all
   public List<Object> getJAXBNodesViaXPath(String xpathExpr, Object someJaxbElement, boolean refreshXmlFirst)
      throws JAXBException {

      return XmlUtils.getJAXBNodesViaXPath(binder, someJaxbElement, xpathExpr, refreshXmlFirst);
   }   


The other approach is to use TraversalUtils (see Getting Started for details) - this is the way I tend to do it.

Re: XPath without a MainDocumentPart

PostPosted: Sun Jan 15, 2012 12:38 am
by PeterR
Hello,

first of all, thank you for this excellent library.
I am trying to use it to change docx files - but I have to admit that I am a little bit lost...

Me too, I would like to do a xpath search on a deepCopy.

I tried to follow the approach mentioned above:

>>> marshall to a node rather than a byte array,

How do I create a new empty node ?

Or has someone even rewritten the complete method?
Thank you!
Peter

Re: XPath without a MainDocumentPart

PostPosted: Sun Jan 15, 2012 1:04 pm
by jason
Here now is a class which does it: http://www.docx4java.org/trac/docx4j/changeset/1751

Re: XPath without a MainDocumentPart

PostPosted: Tue Jan 17, 2012 1:48 pm
by PeterR
Dear Jason,

thank you very much for your help!
It is extremely nice from you to write that code !!!

I would never have been able to write that code...

However, there is something strange.

In the Class that you wrote, change the example in the static main method:

At the end Line 200 insert:
---------------

List<Object> results = cloner.getJAXBNodesViaXPath("//w:t", false);

for (Object obj : results)
System.out.println(XmlUtils.marshaltoString(obj, true, true));

--------------

Shouldn't that output all w:t nodes?

It does output w:t nodes, but the last output of the result list is the complete, original XML ?!
Is that a bug or do I just miss something ?

Thank you!!
Peter

Re: XPath without a MainDocumentPart

PostPosted: Tue Jan 17, 2012 8:16 pm
by jason
Hmm, lucky you uncovered that.

Please try http://www.docx4java.org/trac/docx4j/changeset/1752