Saxon-HE Python Processor
saxonche is the official Saxonica Python wheel package for the SaxonC-HE processor, an XML document processor. It provides APIs to run XSLT 3.0 transformations, XQuery 3.1 queries, XPath 3.1, and XML Schema validation. This library allows Python developers to leverage Saxon's robust and standards-compliant XML processing capabilities, including experimental support for draft 4.0 specifications.
Warnings
- gotcha saxonche is the open-source Home Edition (HE). For Professional (PE) or Enterprise (EE) editions, you must install `saxoncpe` or `saxoncee` respectively, and set `license=True` on the `PySaxonProcessor`. These commercial editions require a valid license key.
- gotcha When using `PySaxonProcessor(license=True)` for commercial editions, SaxonC requires a license file. By default, it looks for the license key in the directory identified by the `SAXONC_HOME` environment variable. You can also explicitly set the license file location using `proc.set_configuration_property("http://saxon.sf.net/feature/licenseFileLocation", "/path/to/saxon-license.lic")`.
- gotcha Converting between Python data types and XDM (XML Data Model) types is not always direct. For some types like strings and booleans, there's a close correspondence, but for numbers, dates, URIs, etc., it's less exact. Explicit conversion methods (e.g., `make_string_value`) might be necessary.
- gotcha As `saxonche` is a C extension, linters like Pylint might report `E0611: No name 'PySaxonProcessor' in module 'saxonche'` errors.
- breaking In SaxonC 12.5.0, breaking changes were introduced to `PyXdmFunctionItem` methods: `get_system_function()` is now a static method (previously an instance method), and the `PySaxonProcessor` argument has been removed from the `call()` method.
- gotcha When using the Python API on Windows, the specific `PySaxonApiError` exception is not available. Instead, a generic `RuntimeError` is thrown if any failures occur internally within SaxonC.
Install
-
pip install saxonche
Imports
- PySaxonProcessor
from saxonche import PySaxonProcessor
Quickstart
import os
from saxonche import PySaxonProcessor
# Create dummy XML and XSLT files for the example
xml_content = """
<doc>
<item>Value 1</item>
<item>Value 2</item>
</doc>
"""
xstl_content = """
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="doc">
<output>
<xsl:apply-templates select="item"/>
</output>
</xsl:template>
<xsl:template match="item">
<transformed-item>
<xsl:value-of select="."/>
</transformed-item>
</xsl:template>
</xsl:stylesheet>
"""
with open("input.xml", "w") as f:
f.write(xml_content)
with open("transform.xsl", "w") as f:
f.write(xstl_content)
try:
# Initialize Saxon processor (license=False for open-source HE edition)
with PySaxonProcessor(license=False) as proc:
print(f"SaxonC Version: {proc.version()}")
# Create XSLT 3.0 processor
xslt_processor = proc.new_xslt30_processor()
# Parse XML source document
input_document = proc.parse_xml(xml_file_name="input.xml")
if not input_document:
print(f"Error parsing XML: {proc.error_message()}")
exit(1)
# Compile XSLT stylesheet
stylesheet = xslt_processor.compile_stylesheet(stylesheet_file="transform.xsl")
if not stylesheet:
print(f"Error compiling XSLT: {xslt_processor.error_message()}")
exit(1)
# Perform transformation
output = stylesheet.transform_to_string(xdm_node=input_document)
if not output:
print(f"Error during transformation: {xslt_processor.error_message()}")
exit(1)
print("Transformation Output:")
print(output)
except Exception as e:
print(f"An error occurred: {e}")
finally:
# Clean up dummy files
if os.path.exists("input.xml"):
os.remove("input.xml")
if os.path.exists("transform.xsl"):
os.remove("transform.xsl")