Page 1 of 1

get/manipulate individual slides

PostPosted: Thu Sep 22, 2011 2:59 am
by sanmoy
How to get the reference to xml for each slide so that i can use my own logic to manipulate those xmls. suppose, my pptx has three slides, so i will be having three xmls /ppt/slides/slide1.xml, ..2.xml and ..3.xml. I had written a code
Code: Select all
PresentationMLPackage pMlPackage = PresentationMLPackage.load(new File("C:/simple.pptx"));
      Parts parts = pMlPackage.getParts();
      Map<PartName,Part> allPartsMap = parts.getParts();
      for(PartName partName:allPartsMap.keySet())
      {
         if(partName.getName().contains("/ppt/slides/"))
         {
            SlidePart slidePart = (SlidePart)allPartsMap.get(partName);
                                // here i want to get the xmls to be loaded for manipulation
            //Document doc = XmlUtils.marshaltoW3CDomDocument(slidePart.getJaxbElement());
         }
      }
pMlPackage.save(new File("C:/simple_out.pptx"));

I had seen code snippets like
Code: Select all
Object obj = XmlUtils.unmarshallFromTemplate(xml, mappings);
      //change  JaxbElement
      documentPart.setJaxbElement(obj);
      SaveToZipFile saver = new SaveToZipFile(wordMLPackage);
      //save  new documnt
      saver.save(newFile);

But I have multiple xmls to be processed.( as there are multiple slides) .

Re: get/manipulate individual slides

PostPosted: Thu Sep 22, 2011 10:27 pm
by jason
Given SlidePart slidePart,

you can manipulate the JAXB representation:
Code: Select all
Sld contents = slidePart.getJaxbElement();


or you can marshal to a dom Node, directly:

Code: Select all
    public void marshal(org.w3c.dom.Node node) throws JAXBException

    public void marshal(org.w3c.dom.Node node,
          Object namespacePrefixMapper) throws JAXBException


or via XmlUtils:

Code: Select all
   public static org.w3c.dom.Document marshaltoW3CDomDocument(Object o, JAXBContext jc)


If you use XmlUtils, you'll need to provide the correct JAXBContext (ie org.pptx4j.jaxb.Context.jcPML)

Regards saving, SaveToZipFile will save the current contents of all your parts. It does this by walking the relationships tree, so all you need to do is make sure that tree is correct (not an issue unless you are adding or re-arranging slides).

Re: get/manipulate individual slides

PostPosted: Sat Sep 24, 2011 10:49 pm
by sanmoy
Thanks for your reply.

But as you have mentioned, we need a dom Node for marshaling. I have searched through Sld API but couldn't find any method to extract the dom node. Also, we cannot pass slidePart.getJaxbElement() to the marshaltoW3CDomDocument method, whilst, this is possible for documentPart.getJaxbElement(). That is why I asked the question about pptx4j and docx4j difference !!

Anyway, my requirement was simple. I had to replace some elements from pptx files which I have achieved through simple java apis. I have used dom4j for xml parsing and jaxen for xpath query. If anyone is interested, he can download the code from http://google-document-translator.googlecode.com/svn/trunk/%20google-document-translator

Re: get/manipulate individual slides

PostPosted: Sun Sep 25, 2011 11:46 am
by jason
sanmoy wrote:But as you have mentioned, we need a dom Node for marshaling. I have searched through Sld API but couldn't find any method to extract the dom node.


As per the Javadoc, you provide a suitable dom node yourself; you don't extract it:

Code: Select all
    /**
     * Marshal the content tree rooted at <tt>jaxbElement</tt> into a DOM tree.
     *
     * @param node
     *      DOM nodes will be added as children of this node.
     *      This parameter must be a Node that accepts children
     *      ({@link org.w3c.dom.Document},
     *      {@link  org.w3c.dom.DocumentFragment}, or
     *      {@link  org.w3c.dom.Element})


sanmoy wrote:Also, we cannot pass slidePart.getJaxbElement() to the marshaltoW3CDomDocument method, whilst, this is possible for documentPart.getJaxbElement().


Why not?

Re: get/manipulate individual slides

PostPosted: Mon Sep 26, 2011 1:50 am
by sanmoy
we cannot pass slidePart.getJaxbElement() to the marshaltoW3CDomDocument method, whilst, this is possible for documentPart.getJaxbElement().

This is because, marshaltoW3CDomDocument internally calls javax.xml.bind.Marshaller.marshall, which expects a jaxb context. Check the below code snippet.

Code: Select all
Parts parts = pMlPackage.getParts();
Map<PartName,Part> allPartsMap = parts.getParts();
SlidePart slidePart = (SlidePart)allPartsMap.get(partName);
Sld sld = slidePart.getJaxbElement();
org.w3c.dom.Document doc = XmlUtils.marshaltoW3CDomDocument(sld);

It will throw the below exception as Sld doesn't come in the class hierarchy..

Code: Select all
java.lang.RuntimeException: javax.xml.bind.JAXBException: class org.pptx4j.pml.Sld nor any of its super class is known to this context.
   at org.docx4j.XmlUtils.marshaltoW3CDomDocument(XmlUtils.java:539)
   at org.docx4j.XmlUtils.marshaltoW3CDomDocument(XmlUtils.java:517)
   at com.ne.PPTXHandler.main(PPTXHandler.java:30)
Caused by: javax.xml.bind.JAXBException: class org.pptx4j.pml.Sld nor any of its super class is known to this context.
   at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getBeanInfo(Unknown Source)
   at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(Unknown Source)
   at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(Unknown Source)
   at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(Unknown Source)
   at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(Unknown Source)
   at org.docx4j.XmlUtils.marshaltoW3CDomDocument(XmlUtils.java:535)
   ... 2 more

Whereas, for document, it will work fine without any exception, as MainDocumentPart extends DocumentPart<org.docx4j.wml.Document>.

Code: Select all
MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
      XmlUtils.marshaltoW3CDomDocument(documentPart.getJaxbElement());

docx4j and pptx4j APIs must be consistent.

Re: get/manipulate individual slides

PostPosted: Mon Sep 26, 2011 9:06 am
by jason
Hi,

As I said earlier in the thread:

If you use XmlUtils, you'll need to provide the correct JAXBContext (ie org.pptx4j.jaxb.Context.jcPML)


The signature without that arg pre-dates the pptx4j component, and remains for convenience (and since most people use docx4j, not pptx)..

Trust that makes sense .. Jason