User-facing documentation for Papercraft XML templates and the X39.Solutions.PdfTemplate compatibility bridge.
| Previous: Complete examples | Manual home | Next: Developer integration appendix |
Troubleshooting collects common reasons a template does not render as expected. It focuses on problems a template author can recognize from the XML, data values or visible output.
Use this chapter when a control is missing, an attribute seems ignored, a value prints empty, an image does not appear, or content moves to another page unexpectedly.
Start from the symptom:
Each troubleshooting entry links back to the concept or reference page that explains the underlying behavior.
Check basic XML syntax first:
< and & need XML escaping.If the error mentions an invalid node name, check for a dot in a normal control name. Style nodes are the special case documented in Styles.
If the error says a control does not exist, check the element name first. Built-in controls are listed in Controls, with focused pages for Rich text, Flow helpers, Lists and Form and signing controls. The compact attribute lookup is in Quick reference. Optional QR and ZXing barcode controls require the package registration documented in QR code control package and ZXing barcode control package.
Common causes:
Developer setup and custom control registration belong in the developer integration appendix.
The manual examples intentionally omit xmlns.
When an element has no XML namespace, the reader treats it as part of the built-in control namespace.
Do not add a custom default namespace to normal templates:
<template xmlns="MyApp.PdfControls">
<body>
<text>Hello</text>
</body>
</template>
In this XML, text is read in MyApp.PdfControls, not in the built-in namespace.
The result is usually an unknown-control error for MyApp.PdfControls:text.
Do not try to fix this with a namespace prefix.
The XML reader rejects prefixed element names such as default:text, even if the prefix points at the current
Papercraft namespace (X39.Solutions.Papercraft) or the legacy X39.Solutions.PdfTemplate.Controls namespace.
This remains invalid:
<template xmlns="MyApp.PdfControls"
xmlns:default="X39.Solutions.PdfTemplate.Controls">
<body>
<default:text>Hello</default:text>
</body>
</template>
For normal authoring, remove the namespace declaration and use unprefixed control names. If a template needs an application-specific control beside built-in controls, ask the application team which unprefixed element name they registered in the normal Papercraft control namespace.
Attributes are not free-form labels. Each control accepts only the parameters implemented for that control.
If an attribute seems to be accepted but has no visible effect, check the focused control page for that attribute. Do not treat ignored attributes as a general fallback behavior; unsupported attribute names are rejected.
Check Controls, the focused control pages and Quick reference for supported attribute names. For package controls, use QR code control package or ZXing barcode control package. For shared spacing, clipping and alignment attributes, see Layout fundamentals.
Layout values are parsed by the type of the attribute.
If a control rejects a value such as length, margin, padding, thickness, color, background or
foreground, check the value format before changing the surrounding layout.
Common checks:
px, pt, mm, cm, in, % or auto.50% for half the available space, not 0.5.red, orange, black, white and transparent, or hex values such as #f00,
#ff0000 and #ff000080.margin, padding and border thickness take one, two or four lengths separated by spaces.
Three values are not supported.1* and 2* are table-column values only; do not use them for normal length attributes.For the full user-facing reference, see Layout fundamentals.
Some controls are containers and some are leaf controls.
For example, border can contain other controls, while text and line render their own content.
If the error says a control does not support child controls, move the child content into a container such as
border, table or the document body.
For the control-authoring mental model, see Control concepts.
Check the exact variable or function name with the application team. Template data names must match what the application supplies. The Template data chapter covers simple variables and data-backed attributes.
If a text value still shows the @ name, such as @OrderNumber, the XML reader did not find a matching variable.
If an attribute value starts with @ and the variable is missing, the evaluated attribute value becomes empty before
control parameter binding. This can later make the control reject the attribute if an empty value is not valid for that
attribute type.
Common checks:
@Customer.Name for nested object fields. In text, the dot stops the variable name, so this is read as @Customer followed by literal .Name.@if condition. Ask for a Boolean flag such as HasOrderNumber, or a Boolean helper function.color="@AccentColor", confirm that the supplied value is a valid value for that attribute.For supported naming patterns, missing-data behavior, optional-value flags and nested-data guidance, see Template data.
Function calls need a closing parenthesis.
Transformer blocks such as @if and @foreach need opening and closing braces.
The XML reader has dedicated exceptions for missing function brackets and missing transformer braces.
@formatTotal(), is reported as a missing function.color="@statusColor()", is reported as a failed expression evaluation.) is reported as a missing closing function bracket.Keep transformer blocks small while debugging. Remove unrelated content until only the failing condition or loop remains, then compare it with Template language.
For @if:
@else if, not bare else if.@else if before the final @else.@else.true or false.For @switch:
@case and @default clauses directly inside the @switch block.@default last.@default only once.@case a value or comparison.For @for:
@for Name from Start to End.step only when the loop should skip values.step when counting up and a negative step when counting down.For @foreach:
in must be a collection supplied by the application or returned by a function.with IndexName part creates a zero-based counter for the block.The built-in image control uses the application resource resolver.
The default resolver accepts base64 image data and data:image/...;base64,... values.
It does not load arbitrary file paths or internet URLs.
If a template needs file, database, object storage or HTTP images, the application must provide a custom resolver. Ask the application team which image source format is supported for your templates. For the template-author reference, see Image control.
Common checks:
source looks like https://example.com/logo.png or C:\Images\logo.png, the default resolver rejects it.source starts with data:image/, it must include the comma and base64 payload, such as data:image/png;base64,....source is plain base64, it still must decode to real image bytes. Base64 text that is not an image fails during image initialization.source="@LogoImage" is used, confirm that the application supplies the image value in the format its resolver expects.Chart data values are parsed as numbers before the chart is drawn.
If no usable data remains, line charts and bar charts render a “No Data Available” message.
Pie charts show the same kind of message when all y values are missing, invalid or add up to zero or less.
Common checks:
3.5 for decimal values, not a localized decimal comma such as 3,5.lineChart and barChart, every visible point or bar needs both numeric x and numeric y values.pieChart, every visible slice needs a numeric y value. x is optional for pie slices.data row does not stop the whole chart, but a chart with only invalid rows has no data to draw.data inside lineChart, barChart or pieChart, not directly inside chart.label, x-label or y-label; use a table when exact labels are required.For the chart authoring reference, see Chart controls.
Content in body is allowed to continue on later pages.
This is normal when the arranged body content is taller than the body space on one page.
Headers, footers and page margins reduce that body space before the body is drawn.
Use this section when the page break is surprising. Start with Page breaks, then check which rule applies.
margin, padding and thickness values.body attribute.border should stay near its content, try
verticalAlignment="top".background and foreground for repeated page-wide marks that should not reserve body space.areas only for fixed-position content that should not affect the body flow.
Area content is clipped to the area rectangle and does not push body content to a later page.Tables have one extra page-break rule.
Table body rows are kept together, so a row can move to the next page even when part of the row might have fit in the
remaining space.
If the table has a th header, the header is rendered again before the moved row.
For table-specific checks, see A table breaks or overflows unexpectedly.
Tables are laid out row by row.
TableControl checks the remaining page height before each body row is rendered.
When the next row is taller than the space left on the current page, the table advances to the next page and renders
the table header again before the row.
Common checks:
th so they can appear again after a table page break.td contents when only a few rows fit on each page.If one body row is taller than a full available page, the table does not split that row into smaller row fragments.
The row is still moved to a fresh page when it does not fit in the remaining space. If the table has a th header,
the header is rendered again before the oversized row. The row then keeps its arranged height, so it can continue
past one page of body space instead of behaving like normal flowing body text.
For long readable content, split the content into several rows or move it out of the table into normal body content.
| Previous: Complete examples | Manual home | Next: Developer integration appendix |