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.

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.0.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.0-py3-none-any.whl (6.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: spans_and_trees-0.3.0.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.0.tar.gz
Algorithm Hash digest
SHA256 1f87755f08376da69ef4f440785458af82bb8b0933c13488545cb046c9ed00d9
MD5 794dcec42f3da6c564519287e2718cd9
BLAKE2b-256 a4c42c50a9595f52efa143cedc7e67e090dd822c2497ef2463909cd6af069c62

See more details on using hashes here.

Provenance

The following attestation bundles were made for spans_and_trees-0.3.0.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.0-py3-none-any.whl.

File metadata

File hashes

Hashes for spans_and_trees-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a19d3c4da9fc5298ece466a217f01fd9984f8cf7bbab4aecffb84909590e729a
MD5 ab366920905100f813ea3d1797130136
BLAKE2b-256 31e172fd855c9327478e8b10a9f63d2d7c838f9fe1b75eb49296c7616e236732

See more details on using hashes here.

Provenance

The following attestation bundles were made for spans_and_trees-0.3.0-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

0.3.1

2 files

This release

0.3.0 This release

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