In PresentationML, relationship plays a very important role. Here is a brief description of it:
Slide : slide.xml.rels contains a relationship id for the slideLayout it references.
SlideMaster : slideMaster.xml.rels contains a relationship Id for the Slidelayout it references.
SlideLayout : slideLayout.xml.rels contains a relationship id for the SlideMaster it references.
Presentation : presentation.xml.rels file contains relationship id for slideMaster.xml, slide.xml. Make sure that these ID should match with the ID present in the presentation.xml.
Note : Please note that above file(s) can contains other releationshipid for other parts as well. But here I have analyzed files with the minimum functionality.
Here are few tips to check if you are not able to open the package:
1. Make sure that [Content_Types].xml contains all the content types present in the document.
2. Make sure that all the relationship Id present in the *.rels file should match with there is present in the respective part.
3. Please download (http://www.microsoft.com/downloads/details.aspx?FamilyId=46B6BF86-E35D-4870-B214-4D7B72B02BF9&displaylang=en) VSTO power tools which works as a Open XML Package Editor. It’s a graphical treeview-based editor for examining and editing Open XML Package files (including Word, Excel and PowerPoint documents).
How to run this program
=====================
1. Open PowerPoint and save the blank presentation.
2. Extract Presentation.xml,Slide1.xml,SlideLayout1.xml,theme1.xml,SlideMaster1.xml from the package and rename them to Presentation.xml,Slide.xml,SlideLayout.xml,theme.xml,SlideMaster.xml.These are the basic files needed to create a presentationML document.
3. Now you need to remove some extra pieces of information present in the above XML files :
a. Presentation.xml : Open the file and remove <p:notesMasterIdLst> tag if present.
b. SlideMaster.xml : Open the file in notepad and search for <p:sldLayoutIdLst> tag. Please make sure that there should be only one entry present for slide layout. If there are more then 1, please remove them as we are adding only one layout file. By default PowerPoint adds 11 different layout files.
After these changes the XML files should not have any broken references. Make sure the XML file path used in the program is valid.
**********************************
StreamWriter objMain;
XmlDocument xDoc = new XmlDocument();
string strFile = ""; // Variable to hold file name
// Create a blank Presentation Package
PresentationDocument pptMainPres = PresentationDocument.Create(@"c:\test\test.pptx", DocumentFormat.OpenXml.PresentationDocumentType.Presentation);
// Sets the basic structure for Presentation.xml. Set the proper content type and rels type. But Presentation.xml will be empty.
PresentationPart pptMain = pptMainPres.AddPresentationPart();
//Create SlideMaster part
SlideMasterPart pptSlideMaster = pptMain.AddNewPart<SlideMasterPart>();
strFile = "..\\..\\slideMaster.xml";
xDoc.Load(strFile);
objMain = new StreamWriter(pptSlideMaster.GetStream(FileMode.Create, FileAccess.Write));
xDoc.Save(objMain);
//Add Theme part
ThemePart pptThemePart = pptMain.AddNewPart<ThemePart>();
strFile = "..\\..\\theme.xml";
xDoc.Load(strFile);
objMain = new StreamWriter(pptThemePart.GetStream(FileMode.Create, FileAccess.Write));
xDoc.Save(objMain);
//Add SlidePart
SlidePart pptSlidePart = pptMain.AddNewPart<SlidePart>();
strFile = "..\\..\\slide.xml";
xDoc.Load(strFile);
objMain = new StreamWriter(pptSlidePart.GetStream(FileMode.Create, FileAccess.Write));
xDoc.Save(objMain);
//Add SlideLayout to SlideMaster
SlideLayoutPart pptSlideLayout = pptSlideMaster.AddNewPart<SlideLayoutPart>();
strFile = "..\\..\\slideLayout.xml";
xDoc.Load(strFile);
objMain = new StreamWriter(pptSlideLayout.GetStream(FileMode.Create, FileAccess.Write));
xDoc.Save(objMain);
//Add Theme to SlideMaster(Here we are creating relationship b/w slideMater and Theme)
pptSlideMaster.AddPart<ThemePart>(pptThemePart);
//Add SlideMaster to SlideLayout(Here we are creating relation ship b/w slideLayout and SlideMaster)
pptSlideLayout.AddPart<SlideMasterPart>(pptSlideMaster);
//Add SlideLayout to Slide(Here we are creating relation ship b/w slideLayout and Slide)
pptSlidePart.AddPart<SlideLayoutPart>(pptSlideLayout);
//Presentation part xml
strFile = "..\\..\\presentation.xml";
xDoc.Load(strFile);
objMain = new StreamWriter(pptMain.GetStream(FileMode.Create, FileAccess.Write));
xDoc.Save(objMain);
//Get the Slide Master releationshipid generated in Presentation.xml.rels
string releationshipId = pptMain.GetIdOfPart(pptSlideMaster);
// Replace the Slide Master releationshipid in the presentation.xml document so that presentation.xml and Presentation.xml.rels should match
XmlNamespaceManager nsManager = new XmlNamespaceManager(xDoc.NameTable);
nsManager.AddNamespace("p", xDoc.DocumentElement.NamespaceURI);
XmlNodeList nodelist = xDoc.SelectNodes("//p:sldMasterIdLst/p:sldMasterId", nsManager);
foreach (XmlNode node in nodelist)
{
node.Attributes["r:id"].Value = releationshipId;
}
//Get the Slide releationshipid generated in Presentation.xml.rels
releationshipId = pptMain.GetIdOfPart(pptSlidePart);
// Replace the Slide releationshipid in the presentation.xml document so that presentation.xml and Presentation.xml.rels should match
nodelist = xDoc.SelectNodes("//p:sldIdLst/p:sldId", nsManager);
foreach (XmlNode node in nodelist)
{
node.Attributes["r:id"].Value = releationshipId;
}
Stream stream = pptMain.GetStream();
// Save the changes
xDoc.Save(stream);
//Load SlideMaster XML to match the releationship ID
strFile = "..\\..\\slideMaster.xml";
xDoc.Load(strFile);
//get the releationshipid from SlideMaster part
releationshipId = pptSlideMaster.GetIdOfPart(pptSlideLayout);
nsManager = new XmlNamespaceManager(xDoc.NameTable);
nsManager.AddNamespace("p", xDoc.DocumentElement.NamespaceURI);
nodelist = xDoc.SelectNodes("//p:sldLayoutIdLst/p:sldLayoutId", nsManager);
foreach (XmlNode node in nodelist)
{
node.Attributes["r:id"].Value = releationshipId;
}
stream.Flush();
stream = pptSlideMaster.GetStream();
xDoc.Save(stream);
pptMainPres.Close();
**********************************
Ankush