How to Convert XML to PDF with cURL
This tutorial shows how to convert an XML file to PDF with cURL and the pdfRest Convert to PDF API Tool. The request produces tagged output, presents nested XML as a readable hierarchy, and applies page and typography settings without requiring an XML stylesheet or local PDF software.
Why Convert XML to PDF with cURL?
XML is excellent for exchanging structured data between systems, but it is rarely the format a support specialist, project manager, or customer wants to review. Converting XML to PDF creates a portable representation that can be opened consistently, attached to a case, and shared without asking the recipient to use an XML editor.
Consider a scheduled integration that saves a partner’s XML response whenever an order fails. A shell script can send that response to pdfRest, generate a hierarchy-formatted PDF, and attach the document to the incident record. The support team sees parent-child relationships and values without the visual noise of opening and closing tags, while the original XML remains available as the system record.
The same endpoint can use data_presentation: "source" when exact markup is the point of the document. This makes the cURL workflow useful for both reader-friendly diagnostics and syntax-preserving technical evidence, with optional tags and controlled page styling applied during conversion.
cURL Code Example for Converting XML to PDF
#!/bin/sh
# By default, we use the US-based API service. This is the primary endpoint for global use.
API_URL="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
# API_URL="https://eu-api.pdfrest.com"
# This sample converts XML input to a tagged PDF through multipart /pdf.
INPUT_PATH="/path/to/sample.xml"
OPTIONS='{"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"}'
curl --location "$API_URL/pdf" \
--header "Accept: application/json" \
--header "Content-Type: multipart/form-data" \
--header "Api-Key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
--form "file=@$INPUT_PATH" \
--form "structured_text_options=$OPTIONS" \
--form "output=pdf_from_xml"
Source: View the sample on GitHub
Breaking Down the Code
The XML shell example calls cURL directly, so no language package is required. API_URL keeps regional routing visible: the active value uses the US service, and the commented alternative selects the EU service.
#!/bin/sh # By default, we use the US-based API service. This is the primary endpoint for global use. API_URL="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 # API_URL="https://eu-api.pdfrest.com" # This sample converts XML input to a tagged PDF through multipart /pdf. INPUT_PATH="/path/to/sample.xml"
For this XML request, the endpoint excerpt makes the regional service choice explicit:
# By default, we use the US-based API service. This is the primary endpoint for global use. API_URL="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 # API_URL="https://eu-api.pdfrest.com"
INPUT_PATH identifies the local .xml source. The @ prefix in the later --form argument instructs cURL to upload that file’s contents instead of sending its path as text.
# This sample converts XML input to a tagged PDF through multipart /pdf.
INPUT_PATH="/path/to/sample.xml"
OPTIONS='{"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"}'
The JSON assigned to OPTIONS is pdfRest-specific rather than shell syntax. title becomes document metadata, language identifies the document language, and enable_tagging explicitly requests logical structure. page_setup selects Letter portrait pages with 36-point margins, while style supplies fonts, text size, color, and format-specific presentation.
{
"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.
For XML conversion, the --form arguments create the multipart fields: file carries the structured source, structured_text_options carries serialized settings, and output names the requested PDF.
--header "Content-Type: multipart/form-data" \ --header "Api-Key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \ --form "file=@$INPUT_PATH" \ --form "structured_text_options=$OPTIONS" \ --form "output=pdf_from_xml"
The XML request asks for JSON with Accept, declares multipart form data with Content-Type, and authenticates through Api-Key. Success returns the generated PDF resource and download URL; failure returns API error information.
# This sample converts XML input to a tagged PDF through multipart /pdf.
INPUT_PATH="/path/to/sample.xml"
OPTIONS='{"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"}'
curl --location "$API_URL/pdf" \
--header "Accept: application/json" \
--header "Content-Type: multipart/form-data" \
--header "Api-Key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
--form "file=@$INPUT_PATH" \
--form "structured_text_options=$OPTIONS" \
--form "output=pdf_from_xml"
Beyond the Tutorial
Command-line conversion makes it practical to add XML reporting to scheduled jobs, build scripts, and operational diagnostics without first transforming the source into HTML. The hierarchy view favors human review, while source view is better suited to technical records where preserving markup matters.
Tagged output supplies logical structure for accessibility and downstream processing, although enabling tags alone does not establish compliance with a particular accessibility standard. Experiment with the request in API Lab, or consult the Convert to PDF documentation for every supported option.