PyXB-X
PyXB-X ("pixbix") is a pure Python package that generates Python source code for classes that correspond to data structures defined by XMLSchema. It is a re-release of PyXB 1.2.6 under a distinct namespace (`pyxb_x`) to avoid dependency conflicts. The project appears to be in maintenance mode, with its last PyPI release in March 2020 and its upstream PyXB project showing limited recent activity.
Common errors
-
ModuleNotFoundError: No module named 'pyxb.binding'
cause Attempting to import from the original `pyxb` namespace instead of `pyxb_x`, which is where PyXB-X installs its modules.fixChange the import statement from `import pyxb.binding` to `import pyxb_x.binding` (or similarly for other `pyxb` sub-modules). -
AttributeError: 'MyGeneratedElement' object has no attribute 'some_sub_element'
cause Mismatch between the XML element name (case-sensitive) or namespace, and the generated Python attribute name. This can also occur if an optional element is expected but not present in the XML data.fixVerify the XML tag names (including case and namespace) against the generated Python binding class attributes. Ensure required elements are present in the XML. Refer to the generated binding code (`.py` files) for exact attribute names. Use `toxml()` on sample data to debug serialization/deserialization issues. -
subprocess.CalledProcessError: Command '['pyxbgen', '--schema-location=...', ...]' returned non-zero exit status 1.
cause The `pyxbgen` command-line tool was either not found in your system's PATH, or there was an error in the provided XSD file or command-line arguments.fixFirst, ensure `pyxbgen` is installed and accessible (it should be in your virtual environment's `bin` or `Scripts` folder after `pip install pyxb-x`). If it's not directly executable, try running it with `python -m pyxb_x.gen.pyxbgen` instead of just `pyxbgen`. Then, validate your XSD schema for correctness and double-check all command-line arguments.
Warnings
- gotcha PyXB-X installs under the `pyxb_x` namespace, not `pyxb`. All imports must use `pyxb_x` (e.g., `import pyxb_x.binding`). If you have both `pyxb` and `pyxb-x` installed, ensure you are consistently using `pyxb_x` to avoid `ModuleNotFoundError` or conflicts.
- breaking PyXB-X specifically mirrors PyXB version 1.2.6. Be aware that any changes, new features, or breaking API modifications introduced in later conceptual versions of the upstream PyXB project are not present or compatible with `pyxb-x`.
- gotcha Complex XML Schema features (e.g., multiple namespaces, `xsi:type`, `anyURI` types, deeply nested hierarchies, wildcards) can sometimes result in unexpected Python bindings, generation errors, or runtime issues during serialization/deserialization.
Install
-
pip install pyxb-x
Imports
- PyXBGenerator
from pyxb.gen.pyxbgen import PyXBGenerator
from pyxb_x.gen.pyxbgen import PyXBGenerator
- binding_basis
import pyxb.binding.basis
import pyxb_x.binding.basis
- CreateFromDocument
import my_generated_bindings_module parsed_obj = my_generated_bindings_module.CreateFromDocument(xml_data)
Quickstart
import os
import sys
import subprocess
import tempfile
import shutil
# 1. Define a simple XML Schema (XSD)
xsd_content = """<?xml version=\"1.0\"?>
<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">
<xs:element name=\"person\">
<xs:complexType>
<xs:sequence>
<xs:element name=\"name\" type=\"xs:string\"/>
<xs:element name=\"age\" type=\"xs:int\"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
"""
# 2. Set up temporary directory for XSD and generated bindings
temp_dir = tempfile.mkdtemp()
xsd_path = os.path.join(temp_dir, 'example.xsd')
with open(xsd_path, 'w') as f:
f.write(xsd_content)
binding_module_name = 'my_example_bindings'
output_dir = temp_dir
# 3. Use pyxbgen to generate Python bindings
# The `pyxbgen` command-line tool is installed with `pyxb-x`.
# If `pyxbgen` is not found in PATH, use `python -m pyxb_x.gen.pyxbgen`.
# Determine the correct command for pyxbgen
try:
subprocess.check_call(['pyxbgen', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
pyxbgen_cmd = 'pyxbgen'
except (subprocess.CalledProcessError, FileNotFoundError):
pyxbgen_cmd = [sys.executable, '-m', 'pyxb_x.gen.pyxbgen']
generate_command_args = [
f'--schema-location={xsd_path}',
'--binding-language=python',
f'--module={binding_module_name}',
f'--output-directory={output_dir}'
]
full_command = [pyxbgen_cmd] + generate_command_args if isinstance(pyxbgen_cmd, list) else [pyxbgen_cmd] + generate_command_args
print(f"Running generation command: {' '.join(full_command)}")
subprocess.check_call(full_command)
print(f"Bindings generated to: {output_dir}/{binding_module_name}.py")
# 4. Add the output directory to sys.path to import the generated module
sys.path.insert(0, output_dir)
# 5. Import and use the generated bindings
import my_example_bindings
# Create an instance of the 'person' element
p = my_example_bindings.person(name="Alice", age=30)
# Serialize to XML
xml_doc = p.toxml('utf-8', element_name='person')
print("\nGenerated XML:")
print(xml_doc.decode('utf-8'))
# Parse XML back into a Python object
parsed_p = my_example_bindings.CreateFromDocument(xml_doc)
print(f"\nParsed back: Name={parsed_p.name}, Age={parsed_p.age}")
# Clean up temporary files
shutil.rmtree(temp_dir)
print("\nCleaned up temporary files.")