API Reference¶
This page documents every public class, method, property, and function in pygixml. For high-level usage guides see Quick Start, Objectify — Dotted Navigation, and Dictify — XML to Dict.
Core Module¶
pygixml - Python wrapper for pugixml using Cython
A fast and efficient XML parser and manipulator for Python.
- exception pygixml.PygiXMLError¶
Bases:
ValueErrorRaised when a pygixml operation fails.
Typical causes include malformed XML passed to
parse_string()orparse_file(), or an attempt to set a name/value on a null or otherwise invalid node.
- exception pygixml.PygiXMLNullNodeError¶
Bases:
PygiXMLErrorRaised when an operation that requires a valid node is called on a null node (e.g. setting attributes on an element that was never found).
- class pygixml.ParseFlags(value)¶
Bases:
IntFlagBitmask of parse options for
parse_string()andparse_file().Members are combined with the bitwise OR operator (
|). When no flags are supplied the parser usesParseFlags.DEFAULT(all standard processing enabled).Use
ParseFlags.MINIMALwhen you only care about element structure and want the fastest possible parse — it skips escape processing, EOL normalization, and all whitespace handling.Example:
>>> doc = pygixml.parse_string(xml, pygixml.ParseFlags.MINIMAL) >>> # Combine specific flags: >>> flags = pygixml.ParseFlags.COMMENTS | pygixml.ParseFlags.CDATA >>> doc = pygixml.parse_string(xml, flags)
See the Parse Flags section in the documentation for a complete description of each flag.
- CDATA = 4¶
- COMMENTS = 2¶
- DECLARATION = 256¶
- DEFAULT = 116¶
- DOCTYPE = 512¶
- EMBED_PCDATA = 8192¶
- EOL = 32¶
- ESCAPES = 16¶
- FRAGMENT = 4096¶
- FULL = 887¶
- MERGE_PCDATA = 16384¶
- MINIMAL = 0¶
- PI = 1¶
- TRIM_PCDATA = 2048¶
- WCONV_ATTRIBUTE = 64¶
- WNORM_ATTRIBUTE = 128¶
- WS_PCDATA = 8¶
- WS_PCDATA_SINGLE = 1024¶
- class pygixml.XMLAttribute¶
Bases:
objectAn XML attribute on an element (e.g.
id="123").Use
XMLNode.attribute()orXMLNode.first_attribute()to obtain attributes.Example:
>>> doc = pygixml.parse_string('<root id="42" class="main"/>') >>> root = doc.root >>> root.attribute('id').value '42'
- set_name(name)¶
Change the attribute name. Returns
Falseif null.
- set_value(value)¶
Change the attribute value. Returns
Falseif null.
- name¶
Return the attribute name.
- Returns:
str | None
- next_attribute¶
Get next attribute.
- Returns:
Next attribute or None if no next attribute
- Return type:
Example
>>> attr = node.first_attribute() >>> next_attr = attr.next_attribute
- value¶
Return the attribute value.
- Returns:
str | None
- class pygixml.XMLDocument¶
Bases:
objectAn XML document, providing document-level operations.
Use this class to load, create, save, and manipulate XML documents, or to access the root element and top-level children.
The most common entry point is
parse_string()orparse_file(), which return anXMLDocument:>>> doc = pygixml.parse_string('<root><item>value</item></root>') >>> doc.root.child('item').text() 'value'
You can also build a document from scratch:
>>> doc = pygixml.XMLDocument() >>> root = doc.append_child('catalog') >>> item = root.append_child('item') >>> item.set_value('content')
When processing many files in a loop, reuse a single document with
reset()to avoid repeated allocations.- append_child(name)¶
Append a new child element and return it.
- Parameters:
name (str) – Tag name for the new element. Pass an empty string to create a text node instead.
- Returns:
The newly created element (or text node).
- Return type:
Example:
>>> doc = pygixml.XMLDocument() >>> root = doc.append_child('catalog') >>> item = root.append_child('item') >>> item.set_value('content')
- child(name)¶
Return the first child element whose tag matches name, or
Noneif no match is found.- Parameters:
name (str) – Element tag to look for.
- Returns:
XMLNode | None
Example:
>>> doc = pygixml.parse_string('<root><item>value</item></root>') >>> doc.child('item').text() 'value'
- first_child()¶
Return the first child element, or
Noneif the document is empty.- Returns:
XMLNode | None
Example:
>>> doc = pygixml.parse_string('<root><child/></root>') >>> doc.first_child().name 'root'
- load_file(path, options=4294967295)¶
Parse XML from a file and replace the current document content.
Reads and parses the file at path. Returns
Trueon success,Falseif the file cannot be opened or does not contain well-formed XML.- Parameters:
path (str) – Path to the XML file.
options (ParseFlags) – Which parse flags to use. Defaults to
ParseFlags.DEFAULT.
- Returns:
Trueif loading succeeded,Falseotherwise.- Return type:
bool
Example:
>>> doc = pygixml.XMLDocument() >>> doc.load_file('data.xml') True >>> doc.root.name 'root'
- load_string(content, options=4294967295)¶
Parse XML from a string and replace the current document content.
Parses content and replaces whatever the document previously held. Returns
Trueon success,Falseif the string is not well-formed.- Parameters:
content (str) – The XML source text.
options (ParseFlags) – Which parse flags to use. Defaults to
ParseFlags.DEFAULT(full compliance). UseParseFlags.MINIMALfor faster parsing when you don’t need escape processing, EOL normalization, or whitespace handling.
- Returns:
Trueif parsing succeeded,Falseotherwise.- Return type:
bool
Example:
>>> doc = pygixml.XMLDocument() >>> doc.load_string('<root><item>value</item></root>') True >>> doc.root.child('item').text() 'value'
- Raises:
PygiXMLError – When the input is not well-formed XML (raised by
parse_string(); this method returnsFalseinstead).
- reset()¶
Clear all content, returning the document to its initial empty state.
Reuses the same underlying C++ document object, avoiding reallocation overhead when processing many files in a loop.
Example:
>>> doc = pygixml.parse_string('<root>content</root>') >>> doc.reset() >>> doc.root # None — document is empty
- save_file(path, indent=' ')¶
Serialize the document and write it to a file.
- Parameters:
path (str) – Output file path. Existing files will be overwritten.
indent (str) – Indentation string used for pretty-printing. Defaults to two spaces. Pass an empty string for compact output with no indentation.
Example:
>>> doc = pygixml.parse_string('<root><item>value</item></root>') >>> doc.save_file('output.xml') # 2-space indent >>> doc.save_file('compact.xml', indent='') # no indent
- to_string(indent=' ')¶
Serialize the document to an XML string.
- Parameters:
indent (str | int) – Indentation — either a string (e.g.
' ') or a number of spaces (e.g.4). Defaults to two spaces.- Returns:
The serialized XML.
- Return type:
str
Example:
>>> doc = pygixml.parse_string('<root><item>value</item></root>') >>> doc.to_string() '<root>\n <item>value</item>\n</root>' >>> doc.to_string(4) '<root>\n <item>value</item>\n</root>'
- root¶
Return the root element of the document.
Equivalent to calling
first_child(). ReturnsNoneif the document is empty.- Returns:
The root element, or
None.- Return type:
XMLNode | None
Example:
>>> doc = pygixml.parse_string('<root><item>value</item></root>') >>> doc.root.name 'root'
- class pygixml.XMLNode¶
Bases:
objectA single node in the XML tree.
Represents an element, text, comment, processing instruction, or other node type. Provides methods for navigating to related nodes (parent, children, siblings), reading and modifying content, and executing XPath queries scoped to this node.
The most commonly used members are:
child()— first child with a given tagchildren()— iterate direct child elementstext()— combined text contentselect_nodes()/select_node()— XPath selectionxml— serialized XML of this node and its subtree
Example:
>>> doc = pygixml.parse_string('<root><item>value</item></root>') >>> root = doc.root >>> root.child('item').text() 'value'
- static from_mem_id_unsafe(mem_id)¶
Reconstruct an
XMLNodefrom its memory identifier in O(1) time.Unlike
find_mem_id(), which walks the entire tree in O(n) time to locate a node, this method performs an instant lookup.⚠️ Warning: If the mem_id is stale (the node was deleted or the document has been freed), calling methods on the returned object may cause a segmentation fault.
Only use this when you are certain the identifier still belongs to a live node within a valid
XMLDocument.- Parameters:
mem_id (int) – An identifier previously obtained from
node.mem_id.- Returns:
A wrapper for the node at the given identifier.
- Return type:
- Complexity:
O(1) — direct lookup, no tree traversal. Compare with
find_mem_id()which is O(n).
Example:
>>> mid = root.child('item').mem_id >>> node = XMLNode.from_mem_id_unsafe(mid) >>> node.name 'item'
- append_attribute(name)¶
Append a new attribute and return it.
- Parameters:
name (str) – Attribute name.
- Returns:
The newly created attribute.
- Return type:
Example:
>>> root = doc.root >>> attr = root.append_attribute('id') >>> attr.value = '123'
- append_child(name)¶
Append a new child element and return it.
- Parameters:
name (str) – Tag name. Use an empty string to create a text node instead.
- Returns:
The newly created child.
- Return type:
Example:
>>> root = doc.root >>> root.append_child('title').set_value('My Title')
- attribute(name)¶
Return the attribute with the given name, or
None.- Parameters:
name (str) – Attribute name.
- Returns:
XMLAttribute | None
Example:
>>> doc = pygixml.parse_string('<root id="1"/>') >>> doc.root.attribute('id').value '1'
- child(name)¶
Return the first child element whose tag matches name, or
None.- Parameters:
name (str) – Element tag to look for.
- Returns:
XMLNode | None
Example:
>>> doc = pygixml.parse_string('<root><item>value</item></root>') >>> doc.root.child('item').text() 'value'
- child_value(name=None)¶
Return the text content of a child element.
If name is given, finds the first child with that tag and returns its text. Without name, returns the direct text content of this node (i.e. text immediately inside this element, not inside a child).
- Parameters:
name (str | None) – Child tag to look up, or
Nonefor direct text.- Returns:
str | None
Example:
>>> doc = pygixml.parse_string('<root><title>Book</title></root>') >>> doc.root.child_value('title') 'Book'
- children(recursive=False)¶
Iterate over child element nodes.
Note
This is a pygixml-specific feature. pugixml provides
first_child()andnext_sibling()for manual traversal, butchildren()offers a Pythonic one-liner for iterating direct child elements — or all descendants withrecursive=True.Text, comment, and processing-instruction nodes are skipped.
- Parameters:
recursive (bool) – Yield only direct children (
False, the default) or all descendants in depth-first order (True).- Yields:
XMLNode
Example:
>>> doc = pygixml.parse_string('<root><a><a1/></a><b/></root>') >>> [c.name for c in doc.root.children()] ['a', 'b'] >>> [c.name for c in doc.root.children(True)] ['a', 'a1', 'b']
- find_mem_id(mem_id)¶
Look up a descendant node by its memory identifier (see
mem_id).Note
This is a pygixml-specific feature. pugixml has no equivalent — pygixml walks the descendant tree in DFS order comparing node addresses until a match is found.
- Returns:
XMLNode | None
- first_attribute()¶
Return the first attribute on this element, or
Noneif it has none.- Returns:
XMLAttribute | None
Example:
>>> doc = pygixml.parse_string('<root id="1" class="main"/>') >>> doc.root.first_attribute().name 'id'
- first_child()¶
Return the first child element, or
None.- Returns:
XMLNode | None
Example:
>>> doc = pygixml.parse_string('<root><a/><b/></root>') >>> doc.root.first_child().name 'a'
- is_null()¶
Return
Trueif this node is null (i.e. was not found or is invalid).
- prepend_attribute(name)¶
Prepend a new attribute and return it.
- Parameters:
name (str) – Attribute name.
- Returns:
The newly created attribute.
- Return type:
Example:
>>> root = doc.root >>> attr = root.prepend_attribute('id') >>> attr.value = '123'
- prepend_child(name)¶
Preppend a new child element and return it.
- Parameters:
name (str) – Tag name. Use an empty string to create a text node instead.
- Returns:
The newly created child.
- Return type:
Example:
>>> root = doc.root >>> root.preppend_child('title').set_value('My Title')
- remove_attribute(attr)¶
Remove an attribute from this node.
- Parameters:
attr (XMLAttribute) – The attribute to remove.
- Returns:
True if the attribute was successfully removed, False otherwise.
- Return type:
bool
Example:
>>> root = doc.root >>> attr = root.attribute('id') >>> root.remove_attribute(attr) True
- remove_child(node)¶
Remove a direct child element from this node.
- Parameters:
node (XMLNode) – The child node to remove. Must be a direct child of this node.
- Returns:
True if the node was successfully removed, False otherwise.
- Return type:
bool
Example:
>>> child = root.child('old_item') >>> if child: ... root.remove_child(child)
- select_node(query)¶
Run an XPath expression and return the first match, or
None.- Parameters:
query (str) – XPath 1.0 expression.
- Returns:
XPathNode | None
Example:
>>> doc = pygixml.parse_string('<root><a/><b/></root>') >>> doc.root.select_node('b').node.name 'b'
- select_nodes(query)¶
Run an XPath expression and return all matching nodes.
- Parameters:
query (str) – XPath 1.0 expression.
- Returns:
XPathNodeSet
Example:
>>> doc = pygixml.parse_string('<root><a/><b/><a/></root>') >>> len(doc.root.select_nodes('a')) 2
- set_name(name)¶
Change the tag name of this element.
Returns
Falseif the node is null.- Parameters:
name (str) – New tag name.
- Returns:
bool
Example:
>>> doc = pygixml.parse_string('<old/>') >>> doc.root.set_name('new') True >>> doc.root.name 'new'
- set_value(value)¶
Replace the text content of this node.
Returns
Falseif the node is null.- Parameters:
value (str) – New text content.
- Returns:
bool
Example:
>>> doc = pygixml.parse_string('<root><item>old</item></root>') >>> doc.root.child('item').first_child().set_value('new') True
- text(recursive=True, join='\n')¶
Return the combined text content of this node.
Note
This is a pygixml-specific feature. pugixml provides
child_value()for a single child’s text, buttext()recursively collects text from all descendants (optionally non-recursive) and joins the fragments with a configurable separator.- Parameters:
recursive (bool) – When
True(default), gathers text from all descendant text and CDATA nodes. WhenFalse, returns only text that is a direct child of this element.join (str) – String used to join multiple text fragments. Defaults to
\n.
- Returns:
str
Example:
>>> doc = pygixml.parse_string( ... '<root><a>hello</a><b>world</b></root>') >>> doc.root.text() 'hello\nworld' >>> doc.root.text(join=', ') 'hello, world'
- to_string(indent=' ')¶
Serialize this element (and its subtree) to an XML string.
Note
This is a pygixml-specific feature. pugixml can serialize to a file via
save_file(), but it does not provide a method that returns the serialized XML as a Python string. pygixml implements this using an internalstd::ostringstreambuffer.- Parameters:
indent (str | int) – Indentation string or number of spaces. Defaults to two spaces.
- Returns:
str
Example:
>>> doc = pygixml.parse_string('<root><item>val</item></root>') >>> doc.root.child('item').to_string() '<item>val</item>'
- mem_id¶
A unique numeric identifier derived from the node’s internal address.
Note
This is a pygixml-specific feature. The underlying pugixml library does not expose integer node identifiers natively. pygixml provides
mem_idas a safe, hashable handle for debugging, caching, and fast node reconstruction.Returns
0for null nodes.- Returns:
int
- name¶
Return the tag name of this node.
For element nodes this is the element’s tag name. For text, comment, and other non-element nodes this is
None.- Returns:
str | None
Example:
>>> doc = pygixml.parse_string('<root/>') >>> doc.root.name 'root'
- next_element_sibling¶
The next sibling that is an element node, skipping text, comment, and other non-element nodes.
Noneif none.
- next_sibling¶
The next sibling node, or
Noneif this is the last child.
- parent¶
The parent element node. Returns
Nonefor the document root.
- previous_element_sibling¶
The previous sibling that is an element node.
Noneif none.
- previous_sibling¶
The previous sibling node, or
Noneif this is the first child.
- type¶
Return the node type as a human-readable string.
Possible values:
'element','pcdata','cdata','comment','pi','declaration','doctype','document','null'.- Returns:
str
Example:
>>> doc = pygixml.parse_string('<root>text</root>') >>> doc.root.type 'element' >>> doc.root.first_child().type 'pcdata'
- value¶
Return the text content of this node.
For text, CDATA, comment, and processing-instruction nodes, returns the raw value directly.
For element nodes, this is a convenience shortcut that returns the value of the first text/CDATA child (or
Noneif no text child exists).- Returns:
str | None
Example:
# Text node — returns raw value >>> doc = pygixml.parse_string('<root><item>hello</item></root>') >>> doc.root.child('item').first_child().value 'hello' # Element node — returns first text child's value >>> doc.root.child('item').value 'hello'
- xml¶
Shorthand for
self.to_string()— serialized XML with default two-space indentation.Note
This is a pygixml-specific convenience property. pugixml has no equivalent.
- xpath¶
The absolute XPath to this node (e.g.
/root/item[1]/name[1]).Note
This is a pygixml-specific feature. pugixml does not provide XPath generation natively — pygixml implements a custom O(depth) algorithm that walks from the node up to the root, counting same-name siblings to produce accurate positional predicates.
Returns an empty string if the node is not an element.
- Returns:
str
- class pygixml.XPathNode¶
Bases:
objectA single result from an XPath query.
Wraps either an
XMLNode(.node) or anXMLAttribute(.attribute). One of these properties will beNonedepending on what the query matched.Example:
>>> doc = pygixml.parse_string('<root><item id="1">value</item></root>') >>> result = doc.select_node('//item') >>> result.node.name 'item'
- attribute¶
The matched attribute, or
Noneif the query matched an element instead.
- node¶
The matched element, or
Noneif the query matched an attribute instead.
- parent¶
The parent of the matched node (
Nonefor attributes or the document root).
- class pygixml.XPathNodeSet¶
Bases:
objectA collection of
XPathNoderesults from an XPath query.Supports
len(), indexing (node_set[0]), and iteration.Example:
>>> doc = pygixml.parse_string('<root><item>1</item><item>2</item></root>') >>> nodes = doc.select_nodes('//item') >>> len(nodes) 2 >>> nodes[0].node.text() '1'
- class pygixml.XPathQuery¶
Bases:
objectA compiled XPath 1.0 query.
Compiling a query once and re-using it is faster than calling
select_nodes()repeatedly, because the expression is parsed only once.Example:
>>> doc = pygixml.parse_string('<root><item>value</item></root>') >>> query = pygixml.XPathQuery('//item') >>> query.evaluate_node(doc.root).node.text() 'value'
- evaluate_boolean(context_node)¶
Evaluate query and return boolean result.
- Parameters:
context_node (XMLNode) – Node to evaluate the query against
- Returns:
Boolean result of the XPath query
- Return type:
bool
Example
>>> query = pygixml.XPathQuery('count(//item) > 0') >>> has_items = query.evaluate_boolean(doc.first_child()) >>> print(has_items) True
- evaluate_node(context_node)¶
Evaluate query and return first node.
- Parameters:
context_node (XMLNode) – Node to evaluate the query against
- Returns:
First matching XPath node or None if no matches
- Return type:
Example
>>> query = pygixml.XPathQuery('//item') >>> node = query.evaluate_node(doc.first_child()) >>> print(node.node.text())
- evaluate_node_set(context_node)¶
Evaluate query and return node set.
- Parameters:
context_node (XMLNode) – Node to evaluate the query against
- Returns:
Set of matching XPath nodes
- Return type:
Example
>>> query = pygixml.XPathQuery('//item') >>> nodes = query.evaluate_node_set(doc.first_child()) >>> for node in nodes: ... print(node.node.text())
- evaluate_number(context_node)¶
Evaluate query and return numeric result.
- Parameters:
context_node (XMLNode) – Node to evaluate the query against
- Returns:
Numeric result of the XPath query
- Return type:
float
Example
>>> query = pygixml.XPathQuery('count(//item)') >>> count = query.evaluate_number(doc.first_child()) >>> print(count) 2.0
- evaluate_string(context_node)¶
Evaluate query and return string result.
- Parameters:
context_node (XMLNode) – Node to evaluate the query against
- Returns:
String result of the XPath query or None if empty
- Return type:
str
Example
>>> query = pygixml.XPathQuery('//item[1]/text()') >>> text = query.evaluate_string(doc.first_child()) >>> print(text) 'value'
- pygixml.iterfind(source, tag, stack_size=4096, chunk_size=65536)¶
Shortcut for
iterparse(source, events=("end",), tag=tag)that yieldsStreamElementobjects directly (no(event, elem)tuples).Example:
for record in pygixml.iterfind("big.xml", "record"): handle(record) record.clear()
- pygixml.iterparse(source, events=('end',), tag=None, stack_size=4096, chunk_size=65536)¶
Incrementally parse a (possibly huge) XML document.
Yields
(event, element)pairs as each element completes, whereelementis aStreamElement. This never loads the whole document into a pugixml tree; only thePullParser’s lightweight element objects are kept.- Parameters:
source – a file path (
str/os.PathLike), a binary file-like object (anything with.read(n)), or raw XMLbytes/bytearray.events – subset of
("start", "end", "pi"). Default("end",), matchingxml.etree.ElementTree.tag – if given, only elements with this tag produce events (their subtrees are still built normally).
stack_size – see
PullParser.chunk_size – how many bytes to read from source at a time.
Example – process every
<record>while keeping memory bounded:for event, elem in pygixml.iterparse("big.xml", events=("end",)): if elem.tag == "record": handle(elem) elem.clear()
- pygixml.parse_file(file_path, options=4294967295)¶
Parse XML from file and return XMLDocument.
- Parameters:
file_path (str) – Path to XML file
options (ParseFlags, optional) – Parse flags (default:
ParseFlags.DEFAULT). Combine flags with bitwise OR. UseParseFlags.MINIMALfor fastest parsing when you don’t need comments, CDATA, or escape processing.
- Returns:
Parsed XML document
- Return type:
- Raises:
PygiXMLError – If parsing fails
Example
>>> import pygixml >>> doc = pygixml.parse_file('data.xml') >>> doc = pygixml.parse_file('data.xml', pygixml.ParseFlags.MINIMAL)
- pygixml.parse_string(xml_string, options=4294967295)¶
Parse XML from string and return XMLDocument.
- Parameters:
xml_string (str) – XML content as string
options (ParseFlags, optional) – Parse flags (default:
ParseFlags.DEFAULT). Combine flags with bitwise OR. UseParseFlags.MINIMALfor fastest parsing when you don’t need comments, CDATA, or escape processing.
- Returns:
Parsed XML document
- Return type:
- Raises:
PygiXMLError – If parsing fails
Example
>>> import pygixml >>> doc = pygixml.parse_string('<root>content</root>') >>> doc = pygixml.parse_string(xml, pygixml.ParseFlags.MINIMAL)
objectify¶
pygixml.objectify — lxml.objectify-style interface.
All logic lives in objectify.pxi and namespace.pxi, compiled into pygixml_cy.so.
Usage:
from pygixml import objectify
# Plain XML
root = objectify.from_string(xml)
root = objectify.from_file(path)
# Namespace-aware (auto-detected from xmlns declarations)
root = objectify.from_string(xml)
root.find("{http://ns.com}item") # Clark notation
root.find("ns:item") # prefix notation
root.ns_item # dotted access
# Explicit namespace map
root = objectify.from_string(xml, namespaces={"dc": "http://dc.com"})
root.dc_title
- class pygixml.objectify.AttributeMap¶
Bases:
objectDict-like view of all XML attributes on a node.
Provides attribute access via dotted notation, indexing, iteration, and safe
get(). Each access returns a lazyAttributeValue— no string conversion until you ask for it.Access patterns¶
am.id—AttributeValuefor attributeidam["id"]— same via__getitem__am.get("id")—AttributeValueor defaultstr(am.id)— raw string valueam.id()— type-inferred valuefor av in am— iterate all attributes asAttributeValuelen(am)— number of attributes"id" in am— membership testam.keys()— list of attribute namesam.values()— list ofAttributeValueobjectsam.items()— list of(name, AttributeValue)tuplesdict(am)—{name: str_value}plain dict
- get(name, default=None)¶
Return
AttributeValuefor name, or default if absent.
- items()¶
List of
(name, AttributeValue)tuples.
- keys()¶
List of attribute names.
- to_dict(type_infer=False)¶
Return a plain
{name: value}dict.- Parameters:
type_infer – If
True, values are type-inferred (bool/int/float/str). IfFalse(default), all values are plainstr.
- values()¶
List of
AttributeValueobjects.
- class pygixml.objectify.AttributeValue¶
Bases:
objectLazy wrapper around a single XML attribute.
Holds the C-level
xml_attributestruct directly — no string copy or type conversion is performed until explicitly requested.Access patterns¶
str(av)— raw value asstr(cheap: one UTF-8 decode)av()— type-inferred value (bool > int > float > str)av.str()— explicitstrav.int()— explicitintav.float()— explicitfloatav.bool()— explicitboolav.name— attribute name asstrav.raw— raw bytes (no decode — zero-cost)
All conversion methods accept an optional encoding parameter (default
"utf-8").- str()¶
Return the attribute value as a
str.Equivalent to
str(av). Provided for explicit, readable code.
- name¶
Attribute name as a
str.
- raw¶
Raw attribute value as
bytes— zero-cost, no decode.
- class pygixml.objectify.NamespacedElement¶
Bases:
ObjectifiedElementAn
ObjectifiedElementwith namespace-aware lookup.Created automatically by
objectify_from_string()/objectify_from_file()when a namespaces dict is supplied, or when the document containsxmlnsdeclarations andauto_ns=True(default).Supports all three lookup styles:
# Clark notation root.find("{http://ns.com}item") # Prefix notation (colon via find/findall) root.find("ns:item") # Dotted access with registered prefix root.ns_item # expands to <ns:item>
The ns_map is inherited by every child element automatically — you never need to pass it manually.
- find(tag, recursive=True)¶
Namespace-aware find. Accepts Clark notation, prefix notation, or plain names. See
ObjectifiedElement.find().
- findall(tag, recursive=True)¶
Namespace-aware findall. Accepts Clark notation, prefix notation, or plain names. See
ObjectifiedElement.findall().
- ns_map¶
The namespace map
{prefix: uri}active for this element.
- pygixml.objectify.from_file(path, namespaces=None, auto_ns=True, encoding='auto')¶
Parse an XML file and return the root as
ObjectifiedElementorNamespacedElement.- Parameters:
path (str) – Filesystem path to the XML file.
namespaces (dict | None) – Optional
{prefix: uri}map.auto_ns (bool) – Automatically extract
xmlnsdeclarations (defaultTrue).encoding (str) – Input encoding hint. Default
"auto"(detect from BOM or XML declaration). Other values:"utf-8","utf-16","latin-1", etc.
- Returns:
Document root.
- Return type:
- Raises:
PygiXMLError – If the file cannot be read, is malformed, or empty.
Example:
root = objectify_from_file("data.xml") root = objectify_from_file("legacy.xml", encoding="latin-1")
- pygixml.objectify.from_node(node, namespaces=None, auto_ns=True)¶
Wrap an existing
XMLNodeas anObjectifiedElement.No re-parsing is done — the node’s owning document stays alive via the node’s own reference. Useful when you already have a parsed tree and want to switch to the objectify navigation API for a subtree.
- Parameters:
node (XMLNode) – A node from a parsed
XMLDocument.namespaces (dict | None) – Optional
{prefix: uri}map.auto_ns (bool) – Automatically extract
xmlnsdeclarations (defaultTrue).
- Returns:
Wrapped node.
- Return type:
- Raises:
TypeError – If node is not an
XMLNode.PygiXMLError – If node is null.
Example:
doc = pygixml.parse_string(xml) root = objectify.from_node(doc.root) print(root.user_profile.first_name) # wrap a specific child child = doc.root.child("user-profile") elem = objectify.from_node(child) print(elem.first_name)
- pygixml.objectify.from_string(xml, namespaces=None, auto_ns=True, encoding='auto')¶
Parse an XML string and return the root as
ObjectifiedElementorNamespacedElement.- Parameters:
xml (str) – XML source text.
namespaces (dict | None) – Optional
{prefix: uri}map supplied by the caller. Merged with anyxmlnsdeclarations found in the document when auto_ns isTrue.auto_ns (bool) – When
True(default), automatically extractxmlnsdeclarations from the root element and useNamespacedElement. Set toFalseto get a plainObjectifiedElement`regardless of namespace declarations.encoding (str) – Input encoding hint. Default
"auto"(detect from BOM or XML declaration). Other values:"utf-8","utf-16","latin-1", etc.
- Returns:
Document root.
- Return type:
- Raises:
PygiXMLError – If the XML is malformed or has no root element.
Example:
root = objectify_from_string(xml) root = objectify_from_string(xml, encoding="latin-1") root = objectify_from_string(xml, namespaces={"dc": "http://dc.com"})
- class pygixml.objectify.ObjectifiedElement¶
Wraps an XML element node with attribute-style navigation.
Stores the pugixml
xml_nodestruct directly as a C-level field._doc_refkeeps the owningXMLDocumentalive._nsmapholds the inherited namespace map for this node (prefix→uri and uri→prefix entries merged together).Namespace support¶
xmlnsdeclarations are collected automatically during parsing and propagated to child wrappers. Three tag formats are accepted:root.ns_item # underscore → colon mapping root.find("ns:item") # explicit prefix root.find("{http://ns.com}item")# Clark notation
Write support¶
Assignment updates child text or attributes; deletion removes them.
- __bool__()¶
True if self else False
- __call__()¶
Type-inferred text content;
Nonefor empty/structural nodes.
- __eq__(value, /)¶
Return self==value.
- __iter__()¶
Iterate over direct child element nodes.
- __len__()¶
Return len(self).
- __str__()¶
Raw text content, always a plain
str.
- find(tag, recursive=True)¶
Return the first descendant matching tag, or
None.Accepts three tag formats:
"item"— plain tag name"ns:item"— prefixed tag name"{http://ns.com}item"— Clark notation (resolved via nsmap)
- Parameters:
tag (str) – Tag to search for.
recursive (bool) – Search all descendants (default
True).
- Returns:
ObjectifiedElement | None
- findall(tag, recursive=True)¶
Return all descendants matching tag in document order.
Accepts the same tag formats as
find().- Parameters:
tag (str) – Tag to search for.
recursive (bool) – Search all descendants (default
True).
- Returns:
list[ObjectifiedElement]
- get(name, default=None)¶
Return the value of attribute name, or default if absent.
Never raises. Underscore→hyphen fallback applies. Namespace prefix mapping applies when a namespace map is present.
- Parameters:
name (str) – Attribute name.
default – Returned when absent. Defaults to
None.
- attrib¶
All attributes as an
AttributeMap.xmlns declarations are excluded — use
nsmapfor those.Example:
root.attrib["id"] # type-inferred value root.attrib.id # same via dotted access str(root.attrib["id"]) # as string for k, v in root.attrib.items(): ...
- local_name¶
Tag name without namespace prefix (
str).Example:
# For <ns:item>, tag = "ns:item", local_name = "item"
- namespace¶
Namespace URI of this element, or
Noneif not in any namespace.Resolved via the inherited namespace map.
Example:
root = objectify_from_string( '<root xmlns:ns="http://ns.com"><ns:item/></root>') root.ns_item.namespace # 'http://ns.com'
- nsmap¶
{prefix: uri}.Only prefix→uri entries are returned (not the reverse uri→prefix entries that are stored internally for lookup purposes).
Example:
root = objectify_from_string( '<root xmlns:ns="http://ns.com"><ns:item/></root>') root.nsmap # {'ns': 'http://ns.com', '': 'http://default.com'}
- Type:
Namespace map for this element
- prefix¶
Namespace prefix of this element, or
Noneif unprefixed.Example:
# For <ns:item>, prefix = "ns"
- tag¶
The XML tag name of this element (
str).
- text_content¶
Raw text content, always a
str.
- xml¶
Serialised XML of this node and its subtree.
- class pygixml.objectify.NodeSequence¶
A sequence of
ObjectifiedElementsiblings sharing a tag.Supports integer indexing (including negative),
len(), and iteration. When exactly one element is present, calling orstr()-ing the sequence delegates to that sole item.- __bool__()¶
True if self else False
- __call__(*args, **kwargs)¶
Call self as a function.
- __getitem__(key, /)¶
Return self[key].
- __iter__()¶
Implement iter(self).
- __len__()¶
Return len(self).
- __str__()¶
Return str(self).
dictify¶
pygixml.dictify — XML to dict interface, compatible with xmltodict.
All logic lives in dictify.pxi, compiled into pygixml_cy.so.
Usage:
from pygixml import dictify
d = dictify.parse(xml_string)
s = dictify.unparse(d, pretty=True)
d = dictify.parse_file("data.xml")
# streaming: yield one dict per element without loading the whole document
for record in dictify.iterdict("big.xml", "record"):
process(record)
- pygixml.dictify.iterdict(source, tag, attr_prefix='@', cdata_key='#text', force_list=None, stack_size=4096, chunk_size=65536)¶
Stream-parse XML and yield each matching element as a plain
dict, one at a time.Identical to
iterjsonl()except it yieldsStreamElement.to_dict()results instead of JSON strings – useful when you want to keep working with the data in Python rather than as text.Example:
for record in dictify.iterdict("big.xml", "record"): print(record["name"], record["@id"])
- pygixml.dictify.parse(xml, attr_prefix='@', cdata_key='#text', force_list=None, encoding=None)¶
Parse an XML string into an OrderedDict-compatible dict.
Matches the behaviour of the
xmltodictlibrary:Attributes are stored with attr_prefix prepended (default
"@").Text content of mixed nodes is stored under cdata_key (default
"#text").Repeated sibling elements are automatically collapsed into a list.
Empty elements become
None.Whitespace-only text nodes become
None.
- Parameters:
xml (str) – XML source text.
attr_prefix (str) – Prefix for attribute keys. Default
"@".cdata_key (str) – Key for text content in mixed nodes. Default
"#text".force_list (set | True | None) – Tag names that should always be wrapped in a list even when only one element is present. Pass
Trueto force all tags into lists.encoding – Accepted for API compatibility; pygixml auto-detects encoding and this parameter is ignored.
- Returns:
Parsed document as a nested dict.
- Return type:
dict
- Raises:
PygiXMLError – If the XML is malformed.
Example:
from pygixml import dictify d = dictify.parse('<root id="1"><item>a</item><item>b</item></root>') # {'root': {'@id': '1', 'item': ['a', 'b']}}
- pygixml.dictify.parse_file(path, attr_prefix='@', cdata_key='#text', force_list=None)¶
Parse an XML file into a dict. Same semantics as
dictify_parse().- Parameters:
path (str) – Path to the XML file.
attr_prefix (str) – Prefix for attribute keys. Default
"@".cdata_key (str) – Key for text content in mixed nodes.
force_list (set | True | None) – Tags to always wrap in a list.
- Returns:
Parsed document as a nested dict.
- Return type:
dict
- Raises:
PygiXMLError – If the file cannot be read or XML is malformed.
- pygixml.dictify.unparse(input_dict, output=None, encoding='utf-8', full_document='true', indent='\t', attr_prefix='@', cdata_key='#text', pretty=False)¶
Emit an XML string from a dict produced by
dictify_parse().Implemented entirely in C++ — no Python list, string concatenation, or f-string formatting during serialization. Only one Python
stris created at the very end.Matches the
xmltodict.unparsesignature.- Parameters:
input_dict (dict) – A
{root_tag: value}dict.output – Ignored (accepted for API compatibility).
encoding (str) – Encoding declared in the XML header. Default
"utf-8".full_document (str) –
"true"to include the XML declaration.indent (str) – Indentation string when pretty is
True. Default"\t".attr_prefix (str) – Prefix that identifies attribute keys. Default
"@".cdata_key (str) – Key for text content in mixed nodes. Default
"#text".pretty (bool) – Whether to indent output. Default
False.
- Returns:
XML string.
- Return type:
str
- Raises:
ValueError – If input_dict does not have exactly one root key.
Example:
from pygixml import dictify d = {'root': {'@id': '1', 'item': ['a', 'b']}} print(dictify.unparse(d, pretty=True))
jsonify¶
pygixml.jsonify — direct XML → JSON serialization.
All heavy lifting is done in C++ (jsonify.pxi compiled into pygixml_cy.so). No Python dict/list is allocated during traversal — only one str at the end (or, for the streaming entry point below, not even that).
Usage:
from pygixml import jsonify
# smart dispatcher — str or ObjectifiedElement or XMLNode
jsonify.dumps("<root/>")
jsonify.dumps(root.user_profile) # ObjectifiedElement
jsonify.dumps(doc.root) # XMLNode
# typed entry points
jsonify.dumps_str("<root/>")
jsonify.dumps_file("data.xml")
jsonify.dumps_obj(root.user_profile)
jsonify.dumps_node(doc.root)
# options
jsonify.dumps(xml, pretty=True, indent=" ", encoding="utf-8")
jsonify.dumps(xml, attr_prefix="", cdata_key="text")
jsonify.dumps(xml, force_list={"item"})
# streaming, constant-memory conversion for gigantic files:
# pure C++ (yxml + hand-written JSON writer) — no pugixml DOM, no
# Python dict/list, no `json` module, anywhere in the call chain.
# -> JSON Lines / streaming: use jsonify.iterjsonl() (a generator) instead
# of a file-based function — write the file yourself if you need one:
# with open("out.jsonl", "w") as f:
# for line in jsonify.iterjsonl("huge.xml", "record"):
# f.write(line + "\n")
# -> a single standard, valid JSON document (same shape as dumps()),
# using an in-place seek-and-patch trick to avoid buffering whole
# subtrees just to know where array brackets go
jsonify.stream_dump("huge.xml", "huge.json") # compact (default)
jsonify.stream_dump("huge.xml", "huge.json", indent=2) # pretty, 2 spaces
# -> a .jsonl file, written straight from C++ (no per-element
# Python object at all, unlike iterjsonl())
jsonify.stream_jsonl("huge.xml", "huge.jsonl", "record")
- pygixml.jsonify.dumps(source, attr_prefix='@', cdata_key='#text', force_list=None, pretty=False, indent='\t', encoding='utf-8')¶
Serialize XML to JSON — smart dispatcher.
Routes automatically based on source type:
strstarting with<→jsonify_dumps_str()pygixml.ObjectifiedElement→jsonify_dumps_obj()pygixml.XMLNode→jsonify_dumps_node()
Note
File input is intentionally excluded from the dispatcher — use
jsonify_dumps_file()explicitly for files.- Parameters:
source (str | pygixml.ObjectifiedElement | pygixml.XMLNode) – Input XML.
attr_prefix (str) – Prefix for attribute keys. Default
"@".cdata_key (str) – Key for text content. Default
"#text".force_list (set | True | None) – Tags always serialised as array.
pretty (bool) – Indent output. Default
False.indent (str) – Indentation string. Default
"\t".
- Returns:
JSON string.
- Return type:
str
- Raises:
PygiXMLError – If the XML is malformed.
TypeError – If source type is not recognised.
ValueError – If source is a str but does not look like XML.
Example:
from pygixml import jsonify, objectify jsonify.dumps("<root id='1'><item>x</item></root>") jsonify.dumps(root.user_profile) # ObjectifiedElement jsonify.dumps(doc.root) # XMLNode jsonify.dumps_file("data.xml") # file — explicit
- pygixml.jsonify.dumps_file(path, attr_prefix='@', cdata_key='#text', force_list=None, pretty=False, indent='\t', encoding='utf-8')¶
Serialize an XML file directly to JSON.
- Parameters:
path (str) – Filesystem path to the XML file.
- Returns:
JSON string.
- Return type:
str
- Raises:
PygiXMLError – If the file cannot be read or XML is malformed.
- pygixml.jsonify.dumps_node(node, attr_prefix='@', cdata_key='#text', force_list=None, pretty=False, indent='\t', encoding='utf-8')¶
Serialize a low-level
pygixml.XMLNodedirectly to JSON.- Parameters:
node (pygixml.XMLNode) – Node to serialise.
- Returns:
JSON string.
- Return type:
str
- Raises:
TypeError – If node is not an XMLNode.
- pygixml.jsonify.dumps_obj(elem, attr_prefix='@', cdata_key='#text', force_list=None, pretty=False, indent='\t', encoding='utf-8')¶
Serialize an
pygixml.ObjectifiedElementsubtree directly to JSON.- Parameters:
elem (pygixml.ObjectifiedElement) – Element to serialise.
- Returns:
JSON string.
- Return type:
str
- Raises:
TypeError – If elem is not an ObjectifiedElement.
- pygixml.jsonify.dumps_str(xml, attr_prefix='@', cdata_key='#text', force_list=None, pretty=False, indent='\t', encoding='utf-8')¶
Serialize an XML string directly to JSON.
- Parameters:
xml (str) – XML source text.
- Returns:
JSON string.
- Return type:
str
- Raises:
PygiXMLError – If the XML is malformed.
- pygixml.jsonify.iterjsonl(source, tag, attr_prefix='@', cdata_key='#text', force_list=None, stack_size=4096, chunk_size=65536)¶
Stream-parse XML and yield each matching element as a JSON string, one at a time – a generator, not a file.
Built directly on
iterfind()(the same tested, yxml-backed streaming parser used throughout this module) plusStreamElement.to_json(), which serializes one element straight to astrwithout ever constructing an intermediatedictand without using thejsonmodule. Each yielded string is exactly whatjson.dumps()would produce for that element’sStreamElement.to_dict()– but skips building the dict at all.Memory use is bounded by one element’s subtree at a time (the same model as
iterfind()/ElementTree’siterparse– not the whole document), since eachStreamElementis discarded once its JSON string has been produced and the generator moves on.This is the right tool when you want JSON text in Python (to forward over a socket, push into a queue, write your own framing, etc.) without round-tripping through a file. If you actually want a
.jsonlfile on disk, seepygixml.jsonify.stream_jsonl()instead – that one stays in C++ all the way from the XML bytes to the file write, with no per-element Python object (noStreamElement, no dict, no str) ever created.- Parameters:
source (str | os.PathLike | bytes | bytearray | file-like) – Same as
iterparse().tag (str) – Tag name of the elements to convert and yield.
attr_prefix – Same meaning as
StreamElement.to_json().cdata_key – Same meaning as
StreamElement.to_json().force_list – Same meaning as
StreamElement.to_json().stack_size – Same meaning as
iterparse().chunk_size – Same meaning as
iterparse().
- Yields:
str – One JSON object string per matched element.
Examples
for line in jsonify.iterjsonl("big.xml", "record"): send_to_queue(line) # already a JSON string # writing a .jsonl file yourself, if you want one: with open("out.jsonl", "w") as f: for line in jsonify.iterjsonl("big.xml", "record"): f.write(line) f.write("\n")
- pygixml.jsonify.stream_dump(xml_path, json_path, attr_prefix='@', cdata_key='#text', force_list=None, indent=0, stack_size=4096, io_buf_size=65536)¶
Convert a (potentially gigantic) XML file to a single, standard, valid JSON document — in roughly constant memory.
Unlike
stream_jsonl()(which writes JSON Lines — one independent object per line, by design, to sidestep the “do I need an array bracket” problem), this function produces exactly whatdumps()/dumps_file()would produce: one JSON value (an object, mirroring the XML root) that round-trips through a normaljson.loadlike any other JSON file. No pugixml DOM, no Pythondict/list, and nojsonmodule are used internally — every byte is hand-emitted in C++, the same asstream_jsonl().How it stays (mostly) constant-memory while still producing valid JSON syntax: a normal JSON array must know, before its closing
], whether more items follow. Instead of buffering whole subtrees to find out, this engine writes optimistically and patches the file in place once it learns more:The first time a child tag is seen under some parent, a single placeholder byte is reserved right before its value and the tag is written as a plain (non-array) value.
If a second sibling with the same tag shows up, that one placeholder byte is overwritten with
[(an O(1) patch), and the new value is appended right after the first — this is the common case when same-tag siblings are adjacent in the XML, and it never needs to move any bytes around.If XML interleaves a different child in between two same-tag siblings, the engine “splices”: it shifts just the bytes written in between forward (using a small fixed-size buffer, in chunks) to open a gap for the new sibling, then continues. This costs time proportional to how much was interleaved, not to the file size, and is the only case where any data movement happens at all.
Because of that splice fallback, worst-case time can exceed
stream_jsonl()’s for documents where repeated sibling tags are heavily interleaved with unrelated children — for typical record-oriented XML (where<tag>repeats appear consecutively) this never triggers and the function runs at full streaming speed.- Parameters:
xml_path (str) – Path to the input XML file.
json_path (str) – Path to the output JSON file. Overwritten if it exists.
attr_prefix (str) – Prefix for XML attribute names in JSON keys. Default
"@".cdata_key (str) – JSON key used for an element’s text content when mixed with attributes or child elements. Default
"#text".force_list (set[str] | True | None) – Tag names that should always be serialised as a JSON array, even when only one sibling exists for a given parent. Pass
Trueto force every child tag into an array. Default None (a tag becomes an array only when more than one sibling with that name actually appears under the same parent) — matchingdumps()’s default behaviour.indent (int) – Number of spaces to indent nested structures with, following the same convention as Python’s
json.dump(..., indent=N).0(the default) produces compact output with no extra whitespace. Any positive value enables multi-line, indented output using that many spaces per nesting level.stack_size (int) – Size in bytes of yxml’s internal name stack.
io_buf_size (int) – Bytes read per XML I/O operation. Default
65536(64 KB).
- Returns:
Number of XML elements processed (informational).
- Return type:
int
- Raises:
PygiXMLError – On malformed XML, or if the input/output file cannot be opened.
Examples
from pygixml import jsonify jsonify.stream_dump("huge.xml", "huge.json") # compact jsonify.stream_dump("huge.xml", "huge.json", indent=2) # pretty import json with open("huge.json") as f: data = json.load(f) # a single, ordinary, valid JSON document
- pygixml.jsonify.stream_jsonl(xml_path, jsonl_path, tag, attr_prefix='@', cdata_key='#text', force_list=None, stack_size=4096, io_buf_size=65536)¶
Stream-convert an XML file straight to a
.jsonlfile, one matched element per line – entirely in C++.Unlike
iterjsonl(), noStreamElementis ever built and no Pythonstr/dict/listis created for the matched elements themselves: the XML bytes are read with the same yxml-based parser used throughout this module, each matched element’s JSON object is assembled in a small in-memory buffer (bounded by that one element’s own subtree, the same constant-memory model asiterfind()), and written straight to the.jsonlfile – nothing crosses into Python until the function returns the count of records written.This is the right tool when the destination really is a file on disk and you don’t need the records in Python at all (e.g. a one-shot batch conversion). If you want each record back as a Python
str(to forward over a socket, filter, re-encode, etc.), useiterjsonl()instead.- Parameters:
xml_path (str) – Path to the source XML file.
jsonl_path (str) – Path to the
.jsonlfile to write (overwritten if it exists).tag (str) – Tag name of the elements to convert and write, one per line.
attr_prefix – Same meaning as
StreamElement.to_json().cdata_key – Same meaning as
StreamElement.to_json().force_list – Same meaning as
StreamElement.to_json().stack_size –
stack_sizeis yxml’s internal element/attribute name stack (same meaning asiterparse()’sstack_size);io_buf_sizeis the read chunk size from the XML file.io_buf_size –
stack_sizeis yxml’s internal element/attribute name stack (same meaning asiterparse()’sstack_size);io_buf_sizeis the read chunk size from the XML file.
- Returns:
The number of matched elements written.
- Return type:
int
Notes
If
tagitself appears nested inside an already-matched element, that inner occurrence is folded in as an ordinary nested field of the outer match (under its own tag-name key) rather than being written as a second, separate line – only the outermost occurrence of a match starts a new JSONL record. This only matters for genuinely self-nested tags; a flat list of repeated sibling records (the common case) is unaffected.Examples
from pygixml import jsonify n = jsonify.stream_jsonl("big.xml", "big.jsonl", "record") print(f"wrote {n} records")
Streaming¶
- class pygixml.StreamElement¶
A small, ElementTree-like XML element produced while streaming.
StreamElementis a standalone, lightweight node – it is not connected to a pugixml document. Each instance has atag,attribdict, optionaltext/tailstrings, and a list of childStreamElementnodes (accessible via iteration, indexing,len(), orchildren).Call
clear()once you’re done with an element (and its subtree) to free the memory it holds – the classiciterparseidiom for keeping peak memory low on huge documents.- __bool__()¶
True if self else False
- __getitem__(key, /)¶
Return self[key].
- __iter__()¶
Implement iter(self).
- __len__()¶
Return len(self).
- __repr__()¶
Return repr(self).
- clear()¶
Drop this element’s attributes, text, tail and children, freeing the memory they hold (the element itself, e.g. as an already-appended child of its parent, is left in place).
- find(path)¶
Return the first descendant matching
path, orNone. Seefindall()for the supported path syntax.
- findall(path)¶
Find descendants matching
path.Supports
"tag"/"a/b/c"(direct-child traversal),"*"(any child) and".//tag"(any descendant). Returns a list, possibly empty.
- findtext(path, default=None)¶
Return
.textof the first match ofpath, or default.
- get(key, default=None)¶
Return
attrib.get(key, default).
- items()¶
Return the
(name, value)attribute pairs.
- iter(tag=None)¶
Depth-first iterate this element and all its descendants, optionally restricted to a given
tag("*"orNonematches everything).
- to_dict(attr_prefix='@', cdata_key='#text', force_list=None)¶
Convert this element (and its subtree) to a plain
dict, using the same convention aspygixml.jsonify.dumps():Attributes become
{attr_prefix + name: value}entries.A child tag that appears more than once (or is listed in force_list, or force_list is
True) becomes alist; otherwise its value is used directly (no list wrapping).Text content is folded in as cdata_key when the element also has attributes or children; otherwise the element’s value is its text (a plain string), matching the scalar shortcut used elsewhere in pygixml’s JSON conversion.
An element with no attributes, no children, and no text becomes
None.
This only ever builds
dict/list/str— no JSON text is produced. Seeto_json()for a direct-to-string version that skips building this dict entirely.
- to_json(attr_prefix='@', cdata_key='#text', force_list=None)¶
Serialize this element (and its subtree) directly to a JSON
str— without ever constructing an intermediatedictorlist, and without using thejsonmodule. Uses the same conventions asto_dict()/jsonify.dumps().This is the fast path for converting many elements one at a time (e.g. from
pygixml.iterfind()) straight to JSON text, skipping the dict-building step entirely:for elem in pygixml.iterfind("big.xml", "record"): line = elem.to_json() # str, ready to write/yield ... elem.clear()
- attrib¶
- children¶
The list of direct child
StreamElementnodes.
- tag¶
- tail¶
- text¶
- class pygixml.PullParser¶
An incremental (“push”) XML parser.
Feed it bytes as they become available via
feed(), then drain completed("start" | "end" | "pi", value)events withread_events(). Callclose()once there is no more input.This is the low-level engine behind
iterparse(); use it directly when XML data arrives incrementally (e.g. from a socket or an async stream) rather than from a file you can simply read in chunks.- Parameters:
events – subset of
("start", "end", "pi")– which eventsread_events()produces. The element tree is always built regardless of events; this only controls what is yielded.tag – if given, only elements whose tag equals tag produce
"start"/"end"events (their subtrees are still built and linked into the document as usual).stack_size – size in bytes of yxml’s internal name stack. Must be large enough to hold the names of all simultaneously-open elements/attributes/PIs plus their nesting depth (each name is stored with a trailing NUL). Increase this for documents with very deep nesting or very long tag/attribute names.
Example:
parser = pygixml.PullParser(events=("start", "end")) for chunk in network_stream: parser.feed(chunk) for event, elem in parser.read_events(): ... parser.close() for event, elem in parser.read_events(): ...
- close()¶
Signal end-of-input.
Validates that the document ended in a valid state (e.g. not mid-comment or with unclosed elements) and flushes any remaining buffered text. Safe to call multiple times.
- feed(data)¶
Feed a chunk of well-formed, UTF-8 encoded XML bytes.
Completed events become available through
read_events(). RaisesPygiXMLErroron malformed XML.
- read_events()¶
Iterate over
(event, value)pairs accumulated so far.eventis"start","end"or"pi". For"start"/"end", value is aStreamElement(the same instance for both events of a given element). For"pi", value is a(target, content)tuple.Draining this generator removes the events from the internal queue – each event is only produced once.
- closed¶
- line¶
Current 1-based line number – useful in error messages.
- position¶
Total number of bytes consumed so far.