Skip to main content

Spans and Trees

PyPi License Tests codecov

A small Python library for converting between XML trees and a span-based structure. This can be useful for extracting sections of text from XML documents and doing special things with some of the tags.

The three functions are tree_to_spans, spans_to_tree and spans_to_passages for converting between an ElementTree element and text with a list of spans. Examples are shown below.

Install

pip install spans-and-trees

tree_to_spans

First create a little example XML tree to convert.

import xml.etree.ElementTree as ET

xmlstring = "<doc><title>Important document</title><contents>Empty</contents></doc>"
root = ET.ElementTree(ET.fromstring(xmlstring)).getroot()

Then use the tree_to_spans function to convert the XML document into the text content with spans.

from spans_and_trees import tree_to_spans

text, spans = tree_to_spans(root)

print(text)  # Important documentEmpty
print(spans) # [(0, 18, 'title', {}), (18, 5, 'contents', {})]

The format of the spans are a tuple of length 4. The element contents are:

  1. The start location of the span
  2. The length of the span
  3. The tag of the span
  4. A dictionary of the attributes of the span.

spans_to_tree

Now we create a dummy document with a block of text and a span at particular offset.

from spans_and_trees import spans_to_tree

text = 'The quick brown fox jumped over the lazy dog'
spans = [ (10,5,'colour',{'dummy_attrib':'5'}) ] # The span starts at 10, has length of 5, is a 'colour' tag and has a dummy attribute.

root = spans_to_tree(text, spans)

print(type(root)) # <class 'xml.etree.ElementTree.Element'>

We can check the XML tree that has been created:

xmlstr = ET.tostring(root)

print(xmlstr) # b'<tree>The quick <colour dummy_attrib="5">brown</colour> fox jumped over the lazy dog</tree>'

The root element's tag defaults to "tree", since spans don't record a tag for the whole document (tree_to_spans doesn't include one either). Pass root_tag to use something else, e.g. spans_to_tree(text, spans, root_tag="doc").

spans_to_passages

spans_to_passages takes the text/spans output of tree_to_spans and splits it into a list of text passages, one per split_tags element (e.g. p, sec), dropping the content of any ignore_tags element (e.g. table), and attaching any keep_tags spans (e.g. bold) that fall within each passage.

from spans_and_trees import tree_to_spans, spans_to_passages

xmlstring = """
<article>
	<sec>
		<title>Introduction</title>
		<p>This is <bold>important</bold> background text.</p>
		<table-wrap>Some table content we want to ignore.</table-wrap>
		<p>A second paragraph follows.</p>
	</sec>
</article>
"""

root = ET.ElementTree(ET.fromstring(xmlstring)).getroot()
text, spans = tree_to_spans(root)

passages = spans_to_passages(text, spans, ignore_tags={'table-wrap'}, split_tags={'title','p'}, keep_tags={'bold'})
for p in passages:
	print(p)

# {'start': 5, 'end': 17, 'text': 'Introduction', 'spans': []}
# {'start': 20, 'end': 54, 'text': 'This is important background text.', 'spans': [(8, 9, 'bold', {})]}
# {'start': 97, 'end': 124, 'text': 'A second paragraph follows.', 'spans': []}

Each passage's start/end are offsets into the original text; each attached span's offsets are relative to the passage's own text.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

spans_and_trees-0.3.1.tar.gz (7.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

spans_and_trees-0.3.1-py3-none-any.whl (6.1 kB view details)

Uploaded Python 3

File details

Details for the file spans_and_trees-0.3.1.tar.gz.

File metadata

  • Download URL: spans_and_trees-0.3.1.tar.gz
  • Upload date:
  • Size: 7.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for spans_and_trees-0.3.1.tar.gz
Algorithm Hash digest
SHA256 a1a3370f6d9bf3bf4e0c002597f703dce196fd57a5f431595351786b0b25dc90
MD5 869b2a123eabe4f6f30f246519a43651
BLAKE2b-256 221c27c8115a2ea0590583b9d3ffa818ef9cdd7666fbba646a9ebab626589316

See more details on using hashes here.

Provenance

The following attestation bundles were made for spans_and_trees-0.3.1.tar.gz:

Publisher: publish.yml on jakelever/spans_and_trees

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file spans_and_trees-0.3.1-py3-none-any.whl.

File metadata

File hashes

Hashes for spans_and_trees-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 68243f4a73a1d2414cb846e79fb9108abf71e1b549573f24d893a9895defebe4
MD5 c72153ace43791a8dd2f9fde4a0707e3
BLAKE2b-256 8cdc204e4498ff151b1ad498c6991ea43045536fde04736ac721cc637a86180a

See more details on using hashes here.

Provenance

The following attestation bundles were made for spans_and_trees-0.3.1-py3-none-any.whl:

Publisher: publish.yml on jakelever/spans_and_trees

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 files

0.3.0

2 files

0.2.0

2 files

0.1.4

1 file

0.1.3

1 file

0.1.2

1 file

0.1.1

1 file

0.1.0

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page