or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

building.mdconfiguration.mdindex.mdparsing.mdprocessing.md

processing.mddocs/

0

# Text Processing

1

2

Built-in text processing functions for common XML data transformations including normalization, type conversion, and namespace handling.

3

4

## Capabilities

5

6

### Processors Module

7

8

The processors module provides built-in text processing functions that can be used with parser and builder options to transform XML data during parsing.

9

10

```javascript { .api }

11

const processors: {

12

normalize: (str: string) => string;

13

firstCharLowerCase: (str: string) => string;

14

stripPrefix: (str: string) => string;

15

parseNumbers: (str: string) => string | number;

16

parseBooleans: (str: string) => string | boolean;

17

};

18

```

19

20

**Usage Examples:**

21

22

```javascript

23

const xml2js = require('xml2js');

24

25

// Access processors

26

const { processors } = xml2js;

27

28

// Use processors individually

29

console.log(processors.normalize('HELLO WORLD')); // 'hello world'

30

console.log(processors.firstCharLowerCase('UserName')); // 'userName'

31

console.log(processors.stripPrefix('ns:ElementName')); // 'ElementName'

32

console.log(processors.parseNumbers('42')); // 42 (number)

33

console.log(processors.parseBooleans('true')); // true (boolean)

34

35

// Use with parser options

36

const parserOptions = {

37

tagNameProcessors: [processors.firstCharLowerCase],

38

valueProcessors: [processors.parseNumbers, processors.parseBooleans],

39

attrNameProcessors: [processors.normalize]

40

};

41

42

const parser = new xml2js.Parser(parserOptions);

43

```

44

45

### normalize Function

46

47

Converts strings to lowercase for case-insensitive processing.

48

49

```javascript { .api }

50

/**

51

* Convert string to lowercase

52

* @param str - Input string to normalize

53

* @returns Lowercase string

54

*/

55

function normalize(str: string): string;

56

```

57

58

**Usage Examples:**

59

60

```javascript

61

const xml2js = require('xml2js');

62

63

// Direct usage

64

const result = xml2js.processors.normalize('PRODUCT');

65

console.log(result); // 'product'

66

67

// In parser configuration

68

const options = {

69

tagNameProcessors: [xml2js.processors.normalize],

70

attrNameProcessors: [xml2js.processors.normalize]

71

};

72

73

const xmlString = '<PRODUCT ID="123"><NAME>Item</NAME></PRODUCT>';

74

xml2js.parseString(xmlString, options, (err, result) => {

75

if (!err) {

76

console.log(result); // Tags and attributes converted to lowercase

77

}

78

});

79

```

80

81

### firstCharLowerCase Function

82

83

Converts the first character of a string to lowercase, useful for camelCase conversion.

84

85

```javascript { .api }

86

/**

87

* Convert first character to lowercase

88

* @param str - Input string to process

89

* @returns String with first character in lowercase

90

*/

91

function firstCharLowerCase(str: string): string;

92

```

93

94

**Usage Examples:**

95

96

```javascript

97

const xml2js = require('xml2js');

98

99

// Direct usage

100

console.log(xml2js.processors.firstCharLowerCase('ProductName')); // 'productName'

101

console.log(xml2js.processors.firstCharLowerCase('UserID')); // 'userID'

102

console.log(xml2js.processors.firstCharLowerCase('XMLParser')); // 'xMLParser'

103

104

// Convert XML tags to camelCase

105

const options = {

106

tagNameProcessors: [xml2js.processors.firstCharLowerCase],

107

explicitArray: false

108

};

109

110

const xmlString = `

111

<UserProfile>

112

<FirstName>John</FirstName>

113

<LastName>Doe</LastName>

114

<EmailAddress>john@example.com</EmailAddress>

115

</UserProfile>

116

`;

117

118

xml2js.parseString(xmlString, options, (err, result) => {

119

if (!err) {

120

console.log(result);

121

// Result will have camelCase property names:

122

// { userProfile: { firstName: 'John', lastName: 'Doe', emailAddress: 'john@example.com' } }

123

}

124

});

125

```

126

127

### stripPrefix Function

128

129

Removes XML namespace prefixes from element and attribute names.

130

131

```javascript { .api }

132

/**

133

* Remove XML namespace prefixes

134

* @param str - Input string that may contain namespace prefix

135

* @returns String with namespace prefix removed

136

*/

137

function stripPrefix(str: string): string;

138

```

139

140

**Usage Examples:**

141

142

```javascript

143

const xml2js = require('xml2js');

144

145

// Direct usage

146

console.log(xml2js.processors.stripPrefix('ns:ProductName')); // 'ProductName'

147

console.log(xml2js.processors.stripPrefix('soap:Envelope')); // 'Envelope'

148

console.log(xml2js.processors.stripPrefix('PlainElement')); // 'PlainElement' (no change)

149

150

// Strip namespaces during parsing

151

const options = {

152

tagNameProcessors: [xml2js.processors.stripPrefix],

153

attrNameProcessors: [xml2js.processors.stripPrefix],

154

explicitArray: false

155

};

156

157

const namespacedXml = `

158

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://example.com/webservice">

159

<soap:Header />

160

<soap:Body>

161

<web:GetUserRequest web:userId="123">

162

<web:UserName>John Doe</web:UserName>

163

</web:GetUserRequest>

164

</soap:Body>

165

</soap:Envelope>

166

`;

167

168

xml2js.parseString(namespacedXml, options, (err, result) => {

169

if (!err) {

170

console.log(result);

171

// Result will have namespace prefixes stripped:

172

// { Envelope: { Header: '', Body: { GetUserRequest: { UserName: 'John Doe' } } } }

173

}

174

});

175

```

176

177

### parseNumbers Function

178

179

Converts numeric strings to JavaScript numbers when possible, leaving non-numeric strings unchanged.

180

181

```javascript { .api }

182

/**

183

* Convert numeric strings to numbers

184

* @param str - Input string to parse

185

* @returns Number if string is numeric, original string otherwise

186

*/

187

function parseNumbers(str: string): string | number;

188

```

189

190

**Usage Examples:**

191

192

```javascript

193

const xml2js = require('xml2js');

194

195

// Direct usage

196

console.log(xml2js.processors.parseNumbers('42')); // 42 (number)

197

console.log(xml2js.processors.parseNumbers('3.14159')); // 3.14159 (number)

198

console.log(xml2js.processors.parseNumbers('-123')); // -123 (number)

199

console.log(xml2js.processors.parseNumbers('0')); // 0 (number)

200

console.log(xml2js.processors.parseNumbers('not a number')); // 'not a number' (string)

201

console.log(xml2js.processors.parseNumbers('')); // '' (string)

202

203

// Parse numbers in XML values

204

const options = {

205

valueProcessors: [xml2js.processors.parseNumbers],

206

explicitArray: false

207

};

208

209

const xmlWithNumbers = `

210

<product>

211

<id>12345</id>

212

<price>99.99</price>

213

<quantity>0</quantity>

214

<discount>-5.50</discount>

215

<name>Smartphone</name>

216

<active>true</active>

217

</product>

218

`;

219

220

xml2js.parseString(xmlWithNumbers, options, (err, result) => {

221

if (!err) {

222

console.log(result);

223

// Numbers are converted: { product: { id: 12345, price: 99.99, quantity: 0, discount: -5.5, name: 'Smartphone', active: 'true' } }

224

}

225

});

226

```

227

228

### parseBooleans Function

229

230

Converts boolean string representations to JavaScript boolean values.

231

232

```javascript { .api }

233

/**

234

* Convert boolean strings to booleans

235

* @param str - Input string to parse

236

* @returns Boolean if string represents true/false, original string otherwise

237

*/

238

function parseBooleans(str: string): string | boolean;

239

```

240

241

**Usage Examples:**

242

243

```javascript

244

const xml2js = require('xml2js');

245

246

// Direct usage

247

console.log(xml2js.processors.parseBooleans('true')); // true (boolean)

248

console.log(xml2js.processors.parseBooleans('false')); // false (boolean)

249

console.log(xml2js.processors.parseBooleans('TRUE')); // true (boolean) - case insensitive

250

console.log(xml2js.processors.parseBooleans('False')); // false (boolean)

251

console.log(xml2js.processors.parseBooleans('yes')); // 'yes' (string) - not converted

252

console.log(xml2js.processors.parseBooleans('1')); // '1' (string) - not converted

253

254

// Parse booleans in XML values

255

const options = {

256

valueProcessors: [xml2js.processors.parseBooleans],

257

attrValueProcessors: [xml2js.processors.parseBooleans],

258

explicitArray: false

259

};

260

261

const xmlWithBooleans = `

262

<settings>

263

<feature enabled="true">

264

<name>Auto-save</name>

265

<active>false</active>

266

<visible>TRUE</visible>

267

</feature>

268

<debug>False</debug>

269

</settings>

270

`;

271

272

xml2js.parseString(xmlWithBooleans, options, (err, result) => {

273

if (!err) {

274

console.log(result);

275

// Booleans are converted: enabled, active, visible, debug become boolean values

276

}

277

});

278

```

279

280

## Combining Multiple Processors

281

282

Processors can be chained together in arrays to apply multiple transformations:

283

284

```javascript

285

const xml2js = require('xml2js');

286

287

// Combine multiple processors

288

const advancedOptions = {

289

// Process tag names: strip namespaces, then convert to camelCase

290

tagNameProcessors: [

291

xml2js.processors.stripPrefix,

292

xml2js.processors.firstCharLowerCase

293

],

294

295

// Process attribute names: normalize to lowercase

296

attrNameProcessors: [

297

xml2js.processors.normalize

298

],

299

300

// Process values: parse numbers and booleans

301

valueProcessors: [

302

xml2js.processors.parseNumbers,

303

xml2js.processors.parseBooleans

304

],

305

306

// Process attribute values: parse numbers and booleans

307

attrValueProcessors: [

308

xml2js.processors.parseNumbers,

309

xml2js.processors.parseBooleans

310

],

311

312

explicitArray: false,

313

mergeAttrs: true

314

};

315

316

const complexXml = `

317

<ns:Product xmlns:ns="http://example.com/products" ID="123" Active="true">

318

<ns:ProductName>Laptop Computer</ns:ProductName>

319

<ns:Price Currency="USD">999.99</ns:Price>

320

<ns:InStock>5</ns:InStock>

321

<ns:Featured>false</ns:Featured>

322

</ns:Product>

323

`;

324

325

xml2js.parseString(complexXml, advancedOptions, (err, result) => {

326

if (!err) {

327

console.log(JSON.stringify(result, null, 2));

328

// Result combines all transformations:

329

// - Namespace prefixes removed

330

// - Tag names converted to camelCase

331

// - Attribute names normalized to lowercase

332

// - Numeric and boolean values properly typed

333

}

334

});

335

```

336

337

## Custom Processors

338

339

You can create custom processor functions that follow the same pattern:

340

341

```javascript

342

const xml2js = require('xml2js');

343

344

// Custom processor to convert snake_case to camelCase

345

function snakeToCamel(str) {

346

return str.replace(/_([a-z])/g, (match, letter) => letter.toUpperCase());

347

}

348

349

// Custom processor to convert units

350

function parseUnits(str) {

351

const match = str.match(/^(\d+(?:\.\d+)?)\s*(px|em|rem|%)$/);

352

if (match) {

353

return {

354

value: parseFloat(match[1]),

355

unit: match[2]

356

};

357

}

358

return str;

359

}

360

361

// Use custom processors

362

const customOptions = {

363

tagNameProcessors: [snakeToCamel],

364

valueProcessors: [parseUnits, xml2js.processors.parseNumbers],

365

explicitArray: false

366

};

367

368

const xmlWithCustomData = `

369

<css_style>

370

<font_size>16px</font_size>

371

<margin_top>2em</margin_top>

372

<opacity>0.8</opacity>

373

</css_style>

374

`;

375

376

xml2js.parseString(xmlWithCustomData, customOptions, (err, result) => {

377

if (!err) {

378

console.log(JSON.stringify(result, null, 2));

379

// Custom processors applied: snake_case -> camelCase, units parsed

380

}

381

});

382

```

383

384

## Processing Order

385

386

When multiple processors are specified in an array, they are applied in order from first to last:

387

388

```javascript

389

const xml2js = require('xml2js');

390

391

// Order matters: first strip prefix, then convert case

392

const options1 = {

393

tagNameProcessors: [

394

xml2js.processors.stripPrefix, // First: 'ns:ProductName' -> 'ProductName'

395

xml2js.processors.firstCharLowerCase // Then: 'ProductName' -> 'productName'

396

]

397

};

398

399

// Different order produces different results

400

const options2 = {

401

tagNameProcessors: [

402

xml2js.processors.firstCharLowerCase, // First: 'ns:ProductName' -> 'ns:productName'

403

xml2js.processors.stripPrefix // Then: 'ns:productName' -> 'productName'

404

]

405

};

406

407

// Both produce the same final result in this case, but order can matter for complex transformations

408

```