Work with PROV-XML¶
PROV-XML support needs the optional lxml dependency:
python -m pip install "prov[xml]"
Serialize to a file¶
import prov.model as pm
document = pm.ProvDocument()
document.set_default_namespace("http://example.org/")
document.entity("e1")
document.serialize("document.xml", format="xml")
Serialize to a string¶
xml_str = document.serialize(format="xml")
print(xml_str)
Force xsd:type attributes¶
By default xsi:type is only written for prov:type, prov:location, and prov:value,
matching the PROV-XML spec examples. Pass force_types=True to write it for every
non-prov: attribute too:
xml_str_typed = document.serialize(format="xml", force_types=True)
Deserialize from a file or stream¶
loaded = pm.ProvDocument.deserialize("document.xml", format="xml")
assert loaded == document
Deserialize from a string¶
loaded = pm.ProvDocument.deserialize(content=xml_str, format="xml")
Auto-detect the format with prov.read()¶
prov.read() tries each registered deserializer in turn — PROV-JSON, then PROV-O/RDF, then
PROV-N, then PROV-XML — treating any failure from a candidate as “not this format” and
moving on to the next one, stopping at the first deserializer that both succeeds and
produces a non-empty document. Valid PROV-XML therefore auto-detects, whether the source is
a file path or raw content:
import prov
loaded = prov.read("document.xml") # no format given
assert loaded == document
A seekable stream source (an open file object, io.StringIO, io.BytesIO, …) is rewound
between auto-detection attempts, so it also auto-detects; a non-seekable stream is consumed
by the first candidate, so pass format="xml" explicitly for those.
Passing format="xml" explicitly skips the trial-and-error and gives the real traceback if
the content is not valid PROV-XML:
loaded = prov.read("document.xml", format="xml")
assert loaded == document
Common errors¶
Malformed XML raises lxml’s own syntax error, not a prov-specific exception:
try:
pm.ProvDocument.deserialize(content="not xml", format="xml")
except Exception as e:
print(f"{type(e).__name__}: {e}")
XMLSyntaxError: Start tag expected, '<' not found, line 1, column 1 (<string>, line 1)