or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

connection-management.mddevice-support.mdindex.mdnetconf-operations.mdtransport-layer.mdxml-utilities.md

xml-utilities.mddocs/

0

# XML Utilities

1

2

Tools for creating, parsing, and manipulating XML documents and NETCONF payloads. NCClient provides a comprehensive XML toolkit with namespace support, NETCONF-specific helpers, and efficient parsing capabilities.

3

4

## Capabilities

5

6

### XML Element Creation

7

8

Functions for creating XML elements and building XML documents programmatically.

9

10

```python { .api }

11

def new_ele(tag, attrs=None, **extra):

12

"""

13

Create new XML element.

14

15

Parameters:

16

- tag: str, element tag name (may include namespace)

17

- attrs: dict, element attributes

18

- **extra: additional attributes as keyword arguments

19

20

Returns:

21

Element: New XML element

22

"""

23

24

def new_ele_ns(tag, ns, attrs=None, **extra):

25

"""

26

Create new XML element with explicit namespace.

27

28

Parameters:

29

- tag: str, element tag name

30

- ns: str, namespace URI

31

- attrs: dict, element attributes

32

- **extra: additional attributes as keyword arguments

33

34

Returns:

35

Element: New namespaced XML element

36

"""

37

38

def sub_ele(parent, tag, attrs=None, **extra):

39

"""

40

Create XML sub-element under parent.

41

42

Parameters:

43

- parent: Element, parent element

44

- tag: str, sub-element tag name

45

- attrs: dict, element attributes

46

- **extra: additional attributes as keyword arguments

47

48

Returns:

49

Element: New sub-element

50

"""

51

52

def sub_ele_ns(parent, tag, ns, attrs=None, **extra):

53

"""

54

Create namespaced XML sub-element under parent.

55

56

Parameters:

57

- parent: Element, parent element

58

- tag: str, sub-element tag name

59

- ns: str, namespace URI

60

- attrs: dict, element attributes

61

- **extra: additional attributes as keyword arguments

62

63

Returns:

64

Element: New namespaced sub-element

65

"""

66

```

67

68

### XML Parsing

69

70

Functions for parsing XML documents and converting between formats.

71

72

```python { .api }

73

def parse_root(raw):

74

"""

75

Parse XML document and return root element.

76

77

Parameters:

78

- raw: str or bytes, XML document content

79

80

Returns:

81

Element: Root element of parsed document

82

"""

83

84

def to_xml(ele, encoding="UTF-8", pretty_print=False):

85

"""

86

Convert XML element to string representation.

87

88

Parameters:

89

- ele: Element, XML element to convert

90

- encoding: str, character encoding (default UTF-8)

91

- pretty_print: bool, format with indentation

92

93

Returns:

94

str: XML string representation

95

"""

96

97

def to_ele(x):

98

"""

99

Convert various inputs to XML element.

100

101

Parameters:

102

- x: str, bytes, file-like object, or Element

103

104

Returns:

105

Element: XML element

106

"""

107

```

108

109

### XML Validation and Utilities

110

111

Helper functions for XML validation and manipulation.

112

113

```python { .api }

114

def validate_xml(xml_string, schema=None):

115

"""

116

Validate XML against schema.

117

118

Parameters:

119

- xml_string: str, XML content to validate

120

- schema: Schema object, validation schema (optional)

121

122

Returns:

123

bool: True if valid, False otherwise

124

"""

125

126

def unqualify(tag):

127

"""

128

Remove namespace qualification from tag name.

129

130

Parameters:

131

- tag: str, qualified tag name

132

133

Returns:

134

str: Unqualified tag name

135

"""

136

137

def qualify(tag, ns=None):

138

"""

139

Add namespace qualification to tag name.

140

141

Parameters:

142

- tag: str, tag name to qualify

143

- ns: str, namespace URI

144

145

Returns:

146

str: Qualified tag name

147

"""

148

```

149

150

## XML Parsers

151

152

Parser objects for handling different XML processing requirements.

153

154

```python { .api }

155

# Standard XML parser

156

parser = etree.XMLParser(recover=False)

157

158

# Parser with huge tree support for large documents

159

huge_parser = etree.XMLParser(recover=False, huge_tree=True)

160

161

def _get_parser(huge_tree=False):

162

"""

163

Get appropriate parser based on requirements.

164

165

Parameters:

166

- huge_tree: bool, whether to use huge tree support

167

168

Returns:

169

XMLParser: Configured XML parser

170

"""

171

```

172

173

## Namespace Constants

174

175

Predefined namespace URIs for common NETCONF and network management schemas.

176

177

```python { .api }

178

# Base NETCONF namespace (RFC 6241)

179

BASE_NS_1_0 = "urn:ietf:params:xml:ns:netconf:base:1.0"

180

181

# YANG namespace (RFC 6020/7950)

182

YANG_NS_1_0 = "urn:ietf:params:xml:ns:yang:1"

183

184

# Cisco NXOS namespaces

185

NXOS_1_0 = "http://www.cisco.com/nxos:1.0"

186

NXOS_IF = "http://www.cisco.com/nxos:1.0:if_manager"

187

CISCO_CPI_1_0 = "http://www.cisco.com/cpi_10/schema"

188

189

# Juniper namespace

190

JUNIPER_1_1 = "http://xml.juniper.net/xnm/1.1/xnm"

191

192

# Huawei namespaces

193

HUAWEI_NS = "http://www.huawei.com/netconf/vrp"

194

HW_PRIVATE_NS = "http://www.huawei.com/netconf/capability/base/1.0"

195

196

# H3C namespaces

197

H3C_DATA_1_0 = "http://www.h3c.com/netconf/data:1.0"

198

H3C_CONFIG_1_0 = "http://www.h3c.com/netconf/config:1.0"

199

H3C_ACTION_1_0 = "http://www.h3c.com/netconf/action:1.0"

200

201

# Nokia/Alcatel-Lucent namespaces

202

ALU_CONFIG = "urn:alcatel-lucent.com:sros:ns:yang:conf-r13"

203

SROS_GLOBAL_OPS_NS = "urn:nokia.com:sros:ns:yang:sr:oper-global"

204

205

# NETCONF standard namespaces

206

NETCONF_MONITORING_NS = "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring"

207

NETCONF_NOTIFICATION_NS = "urn:ietf:params:xml:ns:netconf:notification:1.0"

208

NETCONF_WITH_DEFAULTS_NS = "urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults"

209

210

# Tail-f namespaces

211

TAILF_AAA_1_1 = "http://tail-f.com/ns/aaa/1.1"

212

TAILF_EXECD_1_1 = "http://tail-f.com/ns/execd/1.1"

213

214

# Flowmon namespace

215

FLOWMON_1_0 = "http://www.liberouter.org/ns/netopeer/flowmon/1.0"

216

```

217

218

## XML Error Handling

219

220

Exception classes for XML processing errors.

221

222

```python { .api }

223

class XMLError(NCClientError):

224

"""Exception for XML processing errors."""

225

226

def __init__(self, message, xml_content=None):

227

"""

228

Initialize XML error.

229

230

Parameters:

231

- message: str, error description

232

- xml_content: str, XML content that caused error (optional)

233

"""

234

```

235

236

## NETCONF XML Helpers

237

238

Specialized functions for NETCONF-specific XML operations.

239

240

```python { .api }

241

def build_filter(spec, filter_type="subtree"):

242

"""

243

Build NETCONF filter element.

244

245

Parameters:

246

- spec: str or tuple, filter specification

247

- filter_type: str, filter type ('subtree' or 'xpath')

248

249

Returns:

250

Element: NETCONF filter element

251

"""

252

253

def build_rpc(operation, *args, **kwargs):

254

"""

255

Build NETCONF RPC element.

256

257

Parameters:

258

- operation: str, RPC operation name

259

- *args: positional arguments for operation

260

- **kwargs: keyword arguments for operation

261

262

Returns:

263

Element: NETCONF RPC element

264

"""

265

266

def wrap_rpc_reply(data):

267

"""

268

Wrap data in NETCONF RPC reply envelope.

269

270

Parameters:

271

- data: Element, reply data content

272

273

Returns:

274

Element: NETCONF rpc-reply element

275

"""

276

```

277

278

## Usage Examples

279

280

### Creating XML Elements

281

282

```python

283

from ncclient.xml_ import new_ele, sub_ele, to_xml

284

285

# Create root element

286

config = new_ele("config")

287

288

# Add sub-elements

289

interface = sub_ele(config, "interface")

290

sub_ele(interface, "name").text = "eth0"

291

sub_ele(interface, "description").text = "Management Interface"

292

293

# Convert to XML string

294

xml_string = to_xml(config, pretty_print=True)

295

print(xml_string)

296

```

297

298

### Working with Namespaces

299

300

```python

301

from ncclient.xml_ import new_ele_ns, sub_ele_ns, BASE_NS_1_0

302

303

# Create namespaced elements

304

rpc = new_ele_ns("rpc", BASE_NS_1_0, {"message-id": "101"})

305

get_config = sub_ele_ns(rpc, "get-config", BASE_NS_1_0)

306

source = sub_ele_ns(get_config, "source", BASE_NS_1_0)

307

sub_ele_ns(source, "running", BASE_NS_1_0)

308

309

print(to_xml(rpc, pretty_print=True))

310

```

311

312

### Parsing XML Documents

313

314

```python

315

from ncclient.xml_ import parse_root, to_ele

316

317

# Parse XML from string

318

xml_data = '''

319

<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">

320

<data>

321

<interfaces>

322

<interface>

323

<name>eth0</name>

324

<type>ethernet</type>

325

</interface>

326

</interfaces>

327

</data>

328

</rpc-reply>

329

'''

330

331

# Parse and extract data

332

root = parse_root(xml_data)

333

data = root.find(".//{urn:ietf:params:xml:ns:netconf:base:1.0}data")

334

335

# Work with parsed elements

336

interfaces = data.find(".//interfaces")

337

for interface in interfaces.findall(".//interface"):

338

name = interface.find("name").text

339

iface_type = interface.find("type").text

340

print(f"Interface: {name}, Type: {iface_type}")

341

```

342

343

### Building NETCONF Filters

344

345

```python

346

from ncclient.xml_ import build_filter, new_ele, sub_ele

347

348

# Subtree filter

349

filter_spec = '''

350

<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">

351

<interface>

352

<name/>

353

<type/>

354

<admin-status/>

355

</interface>

356

</interfaces>

357

'''

358

359

# Build filter element

360

filter_elem = build_filter(filter_spec, "subtree")

361

362

# XPath filter

363

xpath_filter = "/interfaces/interface[name='eth0']"

364

xpath_elem = build_filter(xpath_filter, "xpath")

365

```

366

367

### Custom XML Processing

368

369

```python

370

from ncclient.xml_ import parse_root, new_ele, sub_ele, to_xml

371

372

def extract_interface_config(config_xml):

373

"""Extract interface configuration from NETCONF data."""

374

root = parse_root(config_xml)

375

interfaces = []

376

377

# Find all interface elements

378

for interface in root.findall(".//interface"):

379

interface_data = {

380

'name': interface.find("name").text if interface.find("name") is not None else None,

381

'description': interface.find("description").text if interface.find("description") is not None else None,

382

'admin_status': interface.find("admin-status").text if interface.find("admin-status") is not None else None

383

}

384

interfaces.append(interface_data)

385

386

return interfaces

387

388

def build_interface_config(interface_data):

389

"""Build interface configuration XML."""

390

config = new_ele("config")

391

interfaces = sub_ele(config, "interfaces")

392

393

for iface in interface_data:

394

interface = sub_ele(interfaces, "interface")

395

sub_ele(interface, "name").text = iface['name']

396

if iface.get('description'):

397

sub_ele(interface, "description").text = iface['description']

398

if iface.get('admin_status'):

399

sub_ele(interface, "admin-status").text = iface['admin_status']

400

401

return to_xml(config, pretty_print=True)

402

403

# Usage

404

config_data = [

405

{'name': 'eth0', 'description': 'Management', 'admin_status': 'up'},

406

{'name': 'eth1', 'description': 'Data', 'admin_status': 'up'}

407

]

408

409

xml_config = build_interface_config(config_data)

410

print(xml_config)

411

```

412

413

### Error Handling

414

415

```python

416

from ncclient.xml_ import parse_root, XMLError

417

418

def safe_parse_xml(xml_string):

419

"""Safely parse XML with error handling."""

420

try:

421

root = parse_root(xml_string)

422

return root

423

except XMLError as e:

424

print(f"XML parsing error: {e}")

425

return None

426

except Exception as e:

427

print(f"Unexpected error: {e}")

428

return None

429

430

# Parse potentially malformed XML

431

malformed_xml = "<config><interface><name>eth0</interface></config>" # Missing closing tag

432

result = safe_parse_xml(malformed_xml)

433

if result is None:

434

print("Failed to parse XML")

435

```

436

437

### Working with Large XML Documents

438

439

```python

440

from ncclient.xml_ import _get_parser, etree

441

442

def parse_large_xml(xml_data):

443

"""Parse large XML documents with huge tree support."""

444

parser = _get_parser(huge_tree=True)

445

446

try:

447

root = etree.fromstring(xml_data, parser)

448

return root

449

except etree.XMLSyntaxError as e:

450

print(f"XML syntax error: {e}")

451

return None

452

453

# Process large configuration files

454

large_xml_data = open('large_config.xml', 'rb').read()

455

root = parse_large_xml(large_xml_data)

456

if root is not None:

457

print(f"Parsed large XML with {len(root)} child elements")

458

```