PDFML

PDFML is JetsonPDF's declarative XML language for PDFs — clean, prefix-free markup that renders deterministically to ISO 32000-2. Author a document as .pdfml, bind it to your data with WPF-style {Binding} expressions, and turn it into a PDF anywhere .NET runs — or drop the live PdfmlView control onto a WPF / OpenSilver form and watch it re-render as your data changes.

Three ways to use PDFML.

Overview

PDFML is purpose-built for one job — declaring a PDF — rather than retrofitting a screen-oriented format. SVG informed the graphics model and WPF/XAML the layout model, but neither constrained the design. The result is a document format that maps cleanly onto every PDF construct the JetsonPDF writer already produces.

Namespacehttps://schemas.jetsonpdf.com/pdfml/1.0
File extension.pdfml
Media typeapplication/pdfml+xml
RendererJetsonPDF.Pdfmlnet8.0 / netstandard2.0 / net462

The language at a glance

<Document xmlns="https://schemas.jetsonpdf.com/pdfml/1.0" Title="Hello">
  <Page Size="Letter" Margin="1in">
    <TextBlock X="1in" Y="1in" FontSize="32pt" FontWeight="Bold" Foreground="Navy">Hello, PDFML</TextBlock>
  </Page>
</Document>

Dialects

<Document Dialect="WPF|PDF|Mixed"> declares the authoring vocabulary.

Data binding

Data binding is native. Bind any attribute with a WPF-style {Binding path} expression, and use <ItemsControl> + <DataTemplate> for collections. StringFormat, FallbackValue, and TargetNullValue are supported. You supply a data context; the bindings resolve at render time and the emitted PDF is fully static — no live expressions leak into the file.

<Document xmlns="https://schemas.jetsonpdf.com/pdfml/1.0"
          Title="{Binding Number, StringFormat='Invoice {0}'}">
  <Flow Margin="2cm">
    <TextBlock FontSize="22pt" FontWeight="Bold" Text="{Binding Title}" />
    <TextBlock Text="{Binding Customer.Name}" />

    <!-- One row per line item. -->
    <ItemsControl ItemsSource="{Binding Lines}">
      <ItemsControl.ItemTemplate>
        <DataTemplate>
          <Grid CellPadding="4pt">
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="3*" />
              <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" Text="{Binding Description}" />
            <TextBlock Grid.Column="1" TextAlignment="Right" Text="{Binding Amount, StringFormat=C}" />
          </Grid>
        </DataTemplate>
      </ItemsControl.ItemTemplate>
    </ItemsControl>

    <TextBlock TextAlignment="Right" FontWeight="Bold" Text="{Binding Total, StringFormat='Total: {0:C}'}" />
  </Flow>
</Document>

Render to PDF

The JetsonPDF.Pdfml package turns PDFML into a PDF with no dependency on WPF, OpenSilver, or a browser, so it runs anywhere .NET runs — desktop, server, Blazor Server / WASM, and CI. Bindings resolve against a plain data object via reflection.

dotnet add package JetsonPDF.Pdfml
using JetsonPDF.Pdfml;

var data = new
{
    Number   = "INV-2026-001",
    Title    = "Invoice",
    Customer = new { Name = "Acme Corporation" },
    Lines    = new[]
    {
        new { Description = "Design",      Amount = 1200m },
        new { Description = "Development", Amount = 4800m },
    },
    Total = 6000m,
};

var renderer = new PdfmlRenderer();
byte[] pdf = renderer.Render(pdfmlText, data);   // {Binding} resolves against `data`
File.WriteAllBytes("invoice.pdf", pdf);

// Or stream straight to disk / the network:
using var fs = File.Create("invoice.pdf");
renderer.Render(pdfmlText, fs, data);

All three dialects (WPF, PDF, Mixed) and the binding engine ship in this package. Relative Source paths for fonts and images resolve against PdfmlOptions.BaseDirectory.

The PdfmlView control

Drop PdfmlView onto a XAML form, point it at PDFML markup and a data model, and it renders the resulting PDF as a live vector visual tree — then re-renders automatically when the markup or model changes (for example, when a timesheet's date range updates). Ships in both JetsonPDF.Wpf and JetsonPDF.OpenSilver from shared source.

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:jp="clr-namespace:JetsonPDF.Wpf;assembly=JetsonPDF.Wpf">
  <DockPanel>
    <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
      <DatePicker SelectedDate="{Binding Start, Mode=TwoWay}"/>
      <DatePicker SelectedDate="{Binding End,   Mode=TwoWay}"/>
    </StackPanel>

    <!-- Markup is the .pdfml text; Model is the {Binding} data source
         (falls back to DataContext when unset). -->
    <jp:PdfmlView Markup="{Binding Template}" Model="{Binding}"/>
  </DockPanel>
</Window>

A runnable WPF demo lives at samples/PdfmlViewDemo — a timesheet whose preview updates live as you change the date range.

Authoring in Visual Studio

The PDFML Language Support extension makes Visual Studio 2022 / 2026 treat .pdfml files as first-class XML and renders them to PDF as you type.

{Binding} expressions render against a null data context in the editor (there's no sample data), so binding-driven content shows its fallbacks.

Spec & examples

PDFML is a documented, draft standard with a normative XML Schema. The specification, schema, and a set of worked, schema-valid examples live under spec/pdfml/ in the JetsonPDF repository:

Two conformance profiles: Core (structure, layout, graphics, text, color, images, pagination, navigation) and Full (adds forms, annotations, gradients, conformance).

See the full feature matrix → WPF integration →