or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

etree-core.mdhtml-processing.mdindex.mdobjectify-api.mdutility-modules.mdvalidation.mdxpath-xslt.md

objectify-api.mddocs/

0

# Object-Oriented XML API

1

2

Pythonic XML processing that automatically converts XML elements to native Python objects with proper data types. The objectify module provides intuitive attribute-based access to XML content while maintaining full XML structure and namespace support.

3

4

## Capabilities

5

6

### Document Parsing

7

8

Parse XML documents into objectified trees with automatic type conversion.

9

10

```python { .api }

11

def parse(source, parser=None, base_url=None):

12

"""

13

Parse XML document into objectified tree.

14

15

Args:

16

source: File path, URL, or file-like object

17

parser: ObjectifyElementClassLookup-enabled parser (optional)

18

base_url: Base URL for resolving relative references (optional)

19

20

Returns:

21

ObjectifiedElement: Root element with objectified children

22

"""

23

24

def fromstring(text, parser=None, base_url=None):

25

"""

26

Parse XML string into objectified element.

27

28

Args:

29

text: str or bytes containing XML content

30

parser: ObjectifyElementClassLookup-enabled parser (optional)

31

base_url: Base URL for resolving relative references (optional)

32

33

Returns:

34

ObjectifiedElement: Root element with objectified children

35

"""

36

37

def XML(text, parser=None, base_url=None):

38

"""Parse XML string into objectified element with validation."""

39

```

40

41

### Objectified Elements

42

43

Elements that provide Python object-like access to XML content with automatic type conversion.

44

45

```python { .api }

46

class ObjectifiedElement:

47

"""

48

XML element with Python object-like attribute access and type conversion.

49

"""

50

51

# Attribute access - returns child elements or text content

52

def __getattr__(self, name):

53

"""Access child elements as attributes."""

54

55

def __setattr__(self, name, value):

56

"""Set child element content or create new elements."""

57

58

def __delattr__(self, name):

59

"""Remove child elements."""

60

61

# List-like access for multiple children with same name

62

def __getitem__(self, index):

63

"""Access children by index."""

64

65

def __len__(self):

66

"""Number of child elements."""

67

68

def __iter__(self):

69

"""Iterate over child elements."""

70

71

# Dictionary-like access for attributes

72

def get(self, key, default=None):

73

"""Get XML attribute value."""

74

75

def set(self, key, value):

76

"""Set XML attribute value."""

77

78

# Python value conversion

79

def __str__(self):

80

"""String representation of element text content."""

81

82

def __int__(self):

83

"""Integer conversion of element text."""

84

85

def __float__(self):

86

"""Float conversion of element text."""

87

88

def __bool__(self):

89

"""Boolean conversion of element text."""

90

91

# XML methods (inherited from Element)

92

def xpath(self, path, **kwargs):

93

"""XPath evaluation on objectified tree."""

94

95

def find(self, path, namespaces=None):

96

"""Find child elements."""

97

98

def findall(self, path, namespaces=None):

99

"""Find all child elements."""

100

101

class ObjectifiedDataElement:

102

"""Objectified element containing typed data."""

103

104

@property

105

def pyval(self):

106

"""Python value with automatic type conversion."""

107

108

@pyval.setter

109

def pyval(self, value):

110

"""Set Python value with type annotation."""

111

```

112

113

### Data Element Classes

114

115

Specialized element classes for different Python data types.

116

117

```python { .api }

118

class StringElement(ObjectifiedDataElement):

119

"""Element containing string data."""

120

121

class IntElement(ObjectifiedDataElement):

122

"""Element containing integer data."""

123

124

class FloatElement(ObjectifiedDataElement):

125

"""Element containing floating-point data."""

126

127

class BoolElement(ObjectifiedDataElement):

128

"""Element containing boolean data."""

129

130

class NoneElement(ObjectifiedDataElement):

131

"""Element representing None/null value."""

132

133

class NumberElement(ObjectifiedDataElement):

134

"""Element containing numeric data (int or float auto-detected)."""

135

136

def DataElement(_value, _pytype=None, _xsi=None, **kwargs):

137

"""

138

Create data element with specified type.

139

140

Args:

141

_value: Python value to store

142

_pytype: Python type name override

143

_xsi: XML Schema instance type

144

**kwargs: Additional element attributes

145

146

Returns:

147

ObjectifiedDataElement: Typed data element

148

"""

149

```

150

151

### Element Creation

152

153

Factory classes and functions for creating objectified elements.

154

155

```python { .api }

156

class ElementMaker:

157

"""Factory for creating objectified elements with namespace support."""

158

159

def __init__(self, namespace=None, nsmap=None, makeelement=None,

160

typemap=None, **kwargs):

161

"""

162

Create element factory.

163

164

Args:

165

namespace: Default namespace URI

166

nsmap: Namespace prefix mapping

167

makeelement: Custom element factory function

168

typemap: Type mapping for value conversion

169

**kwargs: Default attributes for created elements

170

"""

171

172

def __call__(self, tag, *children, **kwargs):

173

"""Create element with tag, children, and attributes."""

174

175

def __getattr__(self, tag):

176

"""Create element factory function for specific tag."""

177

178

# Default element maker instance

179

E = ElementMaker()

180

181

class ObjectPath:

182

"""

183

Object path for navigating objectified XML trees.

184

"""

185

186

def __init__(self, path):

187

"""

188

Create object path from dot-separated string.

189

190

Args:

191

path: Dot-separated path like "root.child.grandchild"

192

"""

193

194

def find(self, root):

195

"""Find element at path in objectified tree."""

196

197

def setattr(self, root, value):

198

"""Set value at path, creating elements as needed."""

199

200

def hasattr(self, root):

201

"""Test if path exists in tree."""

202

```

203

204

### Type Annotation

205

206

Functions for managing Python type information in XML.

207

208

```python { .api }

209

def annotate(element_or_tree, tag=None, empty_pytype=None,

210

ignore_old=False, ignore_xsi=False, empty_type=None):

211

"""

212

Add Python type annotations to elements based on content.

213

214

Args:

215

element_or_tree: Element or tree to annotate

216

tag: Only annotate elements with this tag

217

empty_pytype: Type to use for empty elements

218

ignore_old: Ignore existing pytype annotations

219

ignore_xsi: Ignore existing xsi:type annotations

220

empty_type: Type class for empty elements

221

"""

222

223

def deannotate(element_or_tree, pytype=True, xsi=True, xsi_nil=True,

224

cleanup_namespaces=False):

225

"""

226

Remove type annotations from elements.

227

228

Args:

229

element_or_tree: Element or tree to process

230

pytype: Remove pytype attributes

231

xsi: Remove xsi:type attributes

232

xsi_nil: Remove xsi:nil attributes

233

cleanup_namespaces: Remove unused namespace declarations

234

"""

235

236

def pyannotate(element_or_tree, ignore_old=False, ignore_xsi=False,

237

empty_type=None):

238

"""Add Python-specific type annotations."""

239

240

def xsiannotate(element_or_tree):

241

"""Add XML Schema instance type annotations."""

242

```

243

244

### Parser Configuration

245

246

Specialized parsers for objectify functionality.

247

248

```python { .api }

249

class ObjectifyElementClassLookup:

250

"""Element class lookup that creates objectified elements."""

251

252

def __init__(self, tree_class=None, empty_data_class=None):

253

"""

254

Create objectify element class lookup.

255

256

Args:

257

tree_class: Class for tree/document elements

258

empty_data_class: Class for empty data elements

259

"""

260

261

def makeparser(**kwargs):

262

"""

263

Create parser configured for objectify processing.

264

265

Args:

266

**kwargs: Parser configuration options

267

268

Returns:

269

XMLParser: Parser with ObjectifyElementClassLookup

270

"""

271

272

def set_default_parser(parser):

273

"""Set default parser for objectify module."""

274

```

275

276

### Utility Functions

277

278

Helper functions for working with objectified trees.

279

280

```python { .api }

281

def dump(element_or_tree):

282

"""Print debug representation of objectified tree."""

283

284

def enable_recursive_str(enabled=True):

285

"""

286

Enable/disable recursive string representation.

287

288

Args:

289

enabled: Enable recursive str() for nested elements

290

"""

291

292

def set_pytype_attribute_tag(attribute_tag=None):

293

"""

294

Configure attribute name for Python type information.

295

296

Args:

297

attribute_tag: Attribute name (None for default)

298

"""

299

300

def pytypename(obj):

301

"""

302

Get Python type name for object.

303

304

Args:

305

obj: Python object

306

307

Returns:

308

str: Type name string

309

"""

310

311

def getRegisteredTypes():

312

"""

313

Get list of registered Python types.

314

315

Returns:

316

list: Registered type classes

317

"""

318

```

319

320

### Type Management

321

322

Classes for managing Python type information.

323

324

```python { .api }

325

class PyType:

326

"""Python type annotation handler."""

327

328

def __init__(self, name, type_check, type_class, stringify=None):

329

"""

330

Register Python type.

331

332

Args:

333

name: Type name string

334

type_check: Function to test if value matches type

335

type_class: Element class for this type

336

stringify: Function to convert value to string

337

"""

338

339

@property

340

def name(self) -> str:

341

"""Type name."""

342

343

@property

344

def xmlSchemaTypes(self) -> list:

345

"""Associated XML Schema types."""

346

```

347

348

## Usage Examples

349

350

### Basic Object-Oriented Access

351

352

```python

353

from lxml import objectify

354

355

# Parse XML with automatic type conversion

356

xml_data = '''<?xml version="1.0"?>

357

<catalog>

358

<book id="1">

359

<title>Python Programming</title>

360

<author>John Smith</author>

361

<year>2023</year>

362

<price>29.99</price>

363

<available>true</available>

364

<chapters>12</chapters>

365

</book>

366

<book id="2">

367

<title>Web Development</title>

368

<author>Jane Doe</author>

369

<year>2022</year>

370

<price>34.95</price>

371

<available>false</available>

372

<chapters>15</chapters>

373

</book>

374

</catalog>'''

375

376

root = objectify.fromstring(xml_data)

377

378

# Access as Python attributes with automatic type conversion

379

print(root.book[0].title) # "Python Programming" (string)

380

print(root.book[0].year) # 2023 (integer)

381

print(root.book[0].price) # 29.99 (float)

382

print(root.book[0].available) # True (boolean)

383

print(root.book[0].chapters) # 12 (integer)

384

385

# Access XML attributes

386

print(root.book[0].get('id')) # "1"

387

388

# Iterate over multiple elements

389

for book in root.book:

390

print(f"{book.title} ({book.year}): ${book.price}")

391

392

# Modify content

393

root.book[0].price = 24.99

394

root.book[0].sale = True # Creates new element

395

396

print(objectify.dump(root))

397

```

398

399

### Creating Objectified XML

400

401

```python

402

from lxml import objectify

403

404

# Create root element

405

root = objectify.Element("products")

406

407

# Add child elements with data

408

root.product = objectify.Element("product", id="1")

409

root.product.name = "Widget"

410

root.product.price = 19.99

411

root.product.in_stock = True

412

root.product.categories = objectify.Element("categories")

413

root.product.categories.category = ["Electronics", "Gadgets"]

414

415

# Add another product

416

product2 = objectify.SubElement(root, "product", id="2")

417

product2.name = "Gadget"

418

product2.price = 15.50

419

product2.in_stock = False

420

421

# Convert to string

422

xml_string = objectify.dump(root)

423

print(xml_string)

424

```

425

426

### Using ElementMaker

427

428

```python

429

from lxml import objectify

430

431

# Create custom ElementMaker

432

E = objectify.ElementMaker(annotate=False)

433

434

# Build XML structure

435

doc = E.order(

436

E.id(12345),

437

E.customer(

438

E.name("John Doe"),

439

E.email("john@example.com")

440

),

441

E.items(

442

E.item(

443

E.product("Widget"),

444

E.quantity(2),

445

E.price(19.99)

446

),

447

E.item(

448

E.product("Gadget"),

449

E.quantity(1),

450

E.price(15.50)

451

)

452

),

453

E.total(55.48),

454

E.date("2023-12-07")

455

)

456

457

# Access created structure

458

print(f"Order ID: {doc.id}")

459

print(f"Customer: {doc.customer.name}")

460

print(f"Total: ${doc.total}")

461

462

for item in doc.items.item:

463

print(f"- {item.product}: {item.quantity} @ ${item.price}")

464

```

465

466

### Object Path Navigation

467

468

```python

469

from lxml import objectify

470

471

xml_data = '''

472

<config>

473

<database>

474

<host>localhost</host>

475

<port>5432</port>

476

<credentials>

477

<username>admin</username>

478

<password>secret</password>

479

</credentials>

480

</database>

481

</config>'''

482

483

root = objectify.fromstring(xml_data)

484

485

# Create object paths

486

host_path = objectify.ObjectPath("database.host")

487

creds_path = objectify.ObjectPath("database.credentials")

488

489

# Navigate using paths

490

print(host_path.find(root)) # "localhost"

491

creds = creds_path.find(root)

492

print(f"User: {creds.username}, Pass: {creds.password}")

493

494

# Set values using paths

495

host_path.setattr(root, "prod-server.com")

496

print(host_path.find(root)) # "prod-server.com"

497

```

498

499

### Type Annotation Control

500

501

```python

502

from lxml import objectify

503

504

xml_data = '''

505

<data>

506

<number>42</number>

507

<decimal>3.14</decimal>

508

<flag>true</flag>

509

<text>hello</text>

510

</data>'''

511

512

root = objectify.fromstring(xml_data)

513

514

# Check current annotations

515

print("Before annotation:")

516

print(objectify.dump(root))

517

518

# Add type annotations

519

objectify.annotate(root)

520

print("\nAfter annotation:")

521

print(objectify.dump(root))

522

523

# Remove annotations

524

objectify.deannotate(root)

525

print("\nAfter deannotation:")

526

print(objectify.dump(root))

527

528

# Custom type handling

529

objectify.set_pytype_attribute_tag("data-type")

530

objectify.annotate(root)

531

print("\nWith custom type attribute:")

532

print(objectify.dump(root))

533

```