How to Convert XML to PDF with PHP
This PHP example converts an XML file with the pdfRest Convert to PDF API Tool and applies structured document settings in the same request. The resulting PDF displays XML data as a tagged hierarchy that is easier to read than raw markup.
Why Convert XML to PDF with PHP?
PHP applications often import XML product catalogs, order acknowledgements, publishing feeds, and records from older web services. Developers can process those files directly, but merchandising, customer service, and operations teams usually need a document they can review without interpreting XML syntax.
Suppose an online marketplace receives a supplier feed containing products, variants, availability, and pricing in nested XML. A PHP job can convert a rejected feed into a hierarchy-formatted PDF and send it with the validation report. The supplier and marketplace team can discuss the same readable snapshot, reducing the chance that an important nested value is overlooked.
When the markup itself must be inspected, changing data_presentation to source produces a formatted code view instead. That choice lets one PHP integration support both business-facing summaries and developer-facing evidence while retaining common PDF styling and tagging controls.
PHP Code Example for Converting XML to PDF
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Utils;
// By default, we use the US-based API service. This is the primary endpoint for global use.
$apiUrl = "https://api.pdfrest.com";
/* For GDPR compliance and enhanced performance for European users, you can switch to the EU-based service by uncommenting the URL below.
* For more information visit https://pdfrest.com/pricing#how-do-eu-gdpr-api-calls-work
*/
//$apiUrl = "https://eu-api.pdfrest.com";
$inputPath = '/path/to/sample.xml';
$options = json_decode('{"title":"Structured Content Sample","language":"en-US","enable_tagging":true,"page_setup":{"size":"Letter","orientation":"portrait","margin":{"top":36,"right":42,"bottom":36,"left":42}},"style":{"font":"Arial","heading_font":"Arial","code_font":"Courier","text_size":11,"text_color_rgb":[34,34,34],"heading_scale":1.35,"table":{"column_width_weights":[2,3,2],"keep_header_with_first_row":true,"repeat_headers_on_overflow":true,"show_borders":true,"border_width":0.75,"border_color_rgb":[180,188,200],"header_fill_color_rgb":[33,64,98],"header_text_color_rgb":[255,255,255],"row_fill_color_rgb":[250,250,252],"alternate_row_fill_color_rgb":[235,240,246],"cell_padding":{"top":6,"right":8,"bottom":6,"left":8}}},"data_presentation":"hierarchy"}', true);
// This sample converts XML input to a tagged PDF through multipart /pdf.
// It demonstrates structured_text_options and the format-specific conversion options.
$multipart = [
['name' => 'file', 'contents' => Utils::tryFopen($inputPath, 'r'), 'filename' => basename($inputPath)],
['name' => 'structured_text_options', 'contents' => json_encode($options)],
['name' => 'output', 'contents' => 'pdf_from_xml'],
];
$response = (new Client())->post($apiUrl . '/pdf', ['headers' => ['Api-Key' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 'Accept' => 'application/json'], 'multipart' => $multipart]);
echo $response->getBody();
Source: View the sample on GitHub
Breaking Down the Code
This PHP XML example relies on Guzzle for HTTP and PSR-7 stream utilities for the upload. When using the code outside this repository, add the client with composer require guzzlehttp/guzzle.
require 'vendor/autoload.php'; use GuzzleHttp\Client; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Utils;
The PHP endpoint excerpt keeps regional routing explicit for this XML operation:
// By default, we use the US-based API service. This is the primary endpoint for global use. $apiUrl = "https://api.pdfrest.com"; /* For GDPR compliance and enhanced performance for European users, you can switch to the EU-based service by uncommenting the URL below. * For more information visit https://pdfrest.com/pricing#how-do-eu-gdpr-api-calls-work */ //$apiUrl = "https://eu-api.pdfrest.com";
PHP opens the .xml source as a PSR-7 stream and includes its filename in the multipart part. The extension selects XML processing without duplicating the format in the options JSON.
$inputPath = '/path/to/sample.xml';
$options = json_decode('{"title":"Structured Content Sample","language":"en-US","enable_tagging":true,"page_setup":{"size":"Letter","orientation":"portrait","margin":{"top":36,"right":42,"bottom":36,"left":42}},"style":{"font":"Arial","heading_font":"Arial","code_font":"Courier","text_size":11,"text_color_rgb":[34,34,34],"heading_scale":1.35,"table":{"column_width_weights":[2,3,2],"keep_header_with_first_row":true,"repeat_headers_on_overflow":true,"show_borders":true,"border_width":0.75,"border_color_rgb":[180,188,200],"header_fill_color_rgb":[33,64,98],"header_text_color_rgb":[255,255,255],"row_fill_color_rgb":[250,250,252],"alternate_row_fill_color_rgb":[235,240,246],"cell_padding":{"top":6,"right":8,"bottom":6,"left":8}}},"data_presentation":"hierarchy"}', true);
The array decoded into $options is serialized as pdfRest’s structured_text_options. It describes the PDF title and language, explicitly turns on tagging, chooses Letter portrait pages with 36-point margins, and provides typography plus XML-specific styling.
{
"data_presentation": "hierarchy"
}
source is the default. It first validates the XML and then displays the user’s original source text, including its markup, whitespace, and declared encoding text. hierarchy instead creates a nested list: local element names become bold labels, attributes appear with an @ prefix, and leaf values follow their element names. Namespace prefixes are not displayed in hierarchy labels. Invalid XML and documents without a root element are rejected in either mode.
The shared style.table member does not affect XML hierarchy or source output. It can be removed from an XML-only profile without changing the resulting document.
The PHP multipart array assigns name and contents values to the XML stream, serialized structured_text_options, and requested output name.
// It demonstrates structured_text_options and the format-specific conversion options. $multipart = [ ['name' => 'file', 'contents' => Utils::tryFopen($inputPath, 'r'), 'filename' => basename($inputPath)], ['name' => 'structured_text_options', 'contents' => json_encode($options)], ['name' => 'output', 'contents' => 'pdf_from_xml'], ]; $response = (new Client())->post($apiUrl . '/pdf', ['headers' => ['Api-Key' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 'Accept' => 'application/json'], 'multipart' => $multipart]); echo $response->getBody();
Guzzle prepares and submits the XML multipart body with the API key. The response body contains generated-resource information on success and service error details when the conversion cannot be completed.
['name' => 'file', 'contents' => Utils::tryFopen($inputPath, 'r'), 'filename' => basename($inputPath)], ['name' => 'structured_text_options', 'contents' => json_encode($options)], ['name' => 'output', 'contents' => 'pdf_from_xml'], ]; $response = (new Client())->post($apiUrl . '/pdf', ['headers' => ['Api-Key' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 'Accept' => 'application/json'], 'multipart' => $multipart]); echo $response->getBody();
Beyond the Tutorial
XML-to-PDF conversion can support invoice-message review, feed diagnostics, and readable exports from content platforms. Hierarchy mode serves mixed technical and business audiences, whereas source mode is useful when reviewers need to see exact element names.
Document tags provide a structural foundation, not an automatic guarantee of conformance with accessibility specifications. Build and inspect request variations in API Lab, then consult the Convert to PDF API documentation for limits and optional settings.