Path Syntax
genro-treestore provides a flexible path syntax for navigating hierarchical structures.
Basic Paths
Label Access
Access nodes by their label:
from genro_treestore import TreeStore
store = TreeStore()
div = store.set_item('div', id='main')
span = div.set_item('span')
# Access by label
node = store['div']
nested = store['div.span']
Positional Access
Use #N to access nodes by position (0-indexed):
store = TreeStore()
store.set_item('div') # #0
store.set_item('span') # #1
store.set_item('p') # #2
first = store['#0'] # First child (div)
second = store['#1'] # Second child (span)
last = store['#-1'] # Last child (p)
Dotted Paths
Chain multiple segments with dots for nested access:
# Label path
store['div.ul.li']
# Positional path
store['#0.#0.#0']
# Mixed path
store['div.#0.li']
Attribute Access
Use ?attr to read or write node attributes:
Reading Attributes
store = TreeStore()
store.set_item('div', color='red', size=10)
color = store['div?color'] # 'red'
size = store['div?size'] # 10
Setting Attributes
store['div?color'] = 'blue'
store['div?new_attr'] = 'value'
Path + Attribute
# Access attribute on nested node
value = store['div.span?class']
store['div.span?class'] = 'highlight'
Special Cases
Non-existent Paths
Accessing non-existent paths raises KeyError:
try:
node = store['nonexistent']
except KeyError:
print("Node not found")
Attribute on Non-existent Node
try:
value = store['nonexistent?attr']
except KeyError:
print("Node not found")
Path Examples
store = TreeStore()
# Build structure
html = store.set_item('html')
body = html.set_item('body')
div = body.set_item('div', id='container')
ul = div.set_item('ul', class_='list')
ul.set_item('li_0', value='Item 1')
ul.set_item('li_1', value='Item 2')
ul.set_item('li_2', value='Item 3')
# Various access patterns
store['html'] # html node
store['html.body'] # body node
store['html.body.div'] # div node
store['#0.#0.#0'] # same as above
store['html.body.div?id'] # 'container'
store['#0.#0.#0.ul.#1'] # second li
store['#0.#0.#0.ul.li_1'] # 'Item 2'
Use Cases
Configuration Trees
config = TreeStore()
db = config.set_item('database')
db.set_item('host', value='localhost')
db.set_item('port', value=5432)
# Access
host = config['database.host'] # 'localhost'
port = config['database.port'] # 5432
DOM-like Structures
page = TreeStore()
page.set_item('header', value='Welcome')
main = page.set_item('main')
main.set_item('article', id='post-1', value='Content...')
page.set_item('footer', value='Copyright 2025')
# Navigation
article_id = page['main.article?id']
With Builders
When using builders, labels follow the tag_N pattern:
from genro_treestore import TreeStore
from genro_treestore.builders import HtmlBuilder
store = TreeStore(builder=HtmlBuilder())
div = store.div(id='main')
div.span(value='Hello')
div.span(value='World')
# Access with auto-generated labels
store['div_0'] # First div
store['div_0.span_0'] # First span inside div
store['div_0.span_1'] # Second span inside div
store['div_0?id'] # 'main'