Working with presentations

The main part of a PresentationML package is ppt/presentation.xml. In ooxmlsdk, it is exposed through PresentationDocument::presentation_part(), and its child relationships connect the presentation to slide, slide master, notes master, handout master, theme, comment author, and other parts.

Use typed part accessors for package navigation whenever possible. They preserve the relationship model and avoid depending on ZIP paths.

PresentationML root

The <p:presentation/> element stores presentation-wide properties and lists the related slides and masters. A small presentation commonly looks like this:

<p:presentation
  xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"
  xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  <p:sldMasterIdLst>
    <p:sldMasterId id="2147483648" r:id="rId1"/>
  </p:sldMasterIdLst>
  <p:sldIdLst>
    <p:sldId id="256" r:id="rId2"/>
    <p:sldId id="257" r:id="rId3"/>
  </p:sldIdLst>
  <p:sldSz cx="9144000" cy="6858000"/>
  <p:notesSz cx="6858000" cy="9144000"/>
</p:presentation>

The r:id values are relationship ids. ooxmlsdk resolves those relationships through the package model.

Common children of p:presentation include:

ElementMeaning
p:sldMasterIdLstSlide masters available in the presentation
p:sldIdLstSlides available in presentation order
p:notesMasterIdLstNotes masters
p:handoutMasterIdLstHandout masters
p:custShowLstCustom slide shows with their own slide ordering
p:sldSzSlide surface size
p:notesSzNotes and handout surface size
p:defaultTextStyleDefault text styles

Slide size describes the presentation slide surface; notes size describes the surface used for notes slides and handouts. Both are separate from the physical package part size.

Common Rust workflow

Open the package, get the presentation part, then traverse child parts:

#![allow(unused)]
fn main() {
use std::io::Cursor;
use std::path::Path;

use ooxmlsdk::parts::comment_authors_part::CommentAuthorsPart;
use ooxmlsdk::parts::presentation_document::PresentationDocument;
use ooxmlsdk::parts::presentation_part::PresentationPart;
use ooxmlsdk::parts::slide_comments_part::SlideCommentsPart;
use ooxmlsdk::parts::slide_part::SlidePart;
use ooxmlsdk::sdk::MediaDataPartType;
use ooxmlsdk::sdk::{OpenSettings, PackageOpenMode, PresentationDocumentType};

pub fn open_presentation_read_only(path: &Path) -> Result<usize, Box<dyn std::error::Error>> {
  let document = PresentationDocument::new_from_file_with_settings(path, lazy_settings())?;
  let presentation_part = document.presentation_part()?;

  Ok(presentation_part.slide_parts(&document).count())
}
}

For read-only analysis, PackageOpenMode::Lazy keeps startup cheap and loads part data as needed. For editing workflows, open the package, mutate supported parts or raw part data deliberately, then call save or copy_to.

Common presentation parts

Package conceptooxmlsdk accessor
Main presentationpresentation_part()
SlidesPresentationPart::slide_parts(&document)
Slide mastersPresentationPart::slide_master_parts(&document)
Notes masterPresentationPart::notes_master_part(&document)
Handout masterPresentationPart::handout_master_part(&document)
ThemePresentationPart::theme_part(&document)
Comment authorsPresentationPart::comment_authors_part(&document)

The Rust API mirrors Open Packaging Convention relationships. Treat the XML schema element names and the package part graph as separate layers: the XML uses r:id, while the SDK resolves that id to a typed part or relationship.