or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdcore-api.mddocument-creation.mdindex.mdio-operations.mdxpath.md

io-operations.mddocs/

0

# DOM4J I/O Operations

1

2

DOM4J provides comprehensive input/output capabilities for reading and writing XML documents. This section covers the I/O classes in the `org.dom4j.io` package, including XML reading, writing, formatting, and integration with various XML processing APIs like SAX, DOM, and STAX.

3

4

## STAXEventReader - StAX Event Stream Reading

5

6

STAXEventReader reads DOM4J documents from StAX XMLEventReader streams, providing integration with Java's StAX API.

7

8

### Package and Import

9

```java { .api }

10

import org.dom4j.io.STAXEventReader;

11

import javax.xml.stream.XMLEventReader;

12

import javax.xml.stream.XMLStreamException;

13

import java.io.*;

14

```

15

16

### STAXEventReader Constructors

17

```java { .api }

18

public class STAXEventReader {

19

// Default constructor with default DocumentFactory

20

public STAXEventReader();

21

22

// Constructor with custom DocumentFactory

23

public STAXEventReader(DocumentFactory factory);

24

}

25

```

26

27

### Document Reading Methods

28

```java { .api }

29

public class STAXEventReader {

30

// Read from streams

31

public Document readDocument(InputStream is) throws XMLStreamException;

32

public Document readDocument(InputStream is, String systemId) throws XMLStreamException;

33

public Document readDocument(Reader reader) throws XMLStreamException;

34

public Document readDocument(Reader reader, String systemId) throws XMLStreamException;

35

36

// Read from StAX event reader

37

public Document readDocument(XMLEventReader eventReader) throws XMLStreamException;

38

39

// Read individual elements

40

public Element readElement(XMLEventReader eventReader) throws XMLStreamException;

41

42

// Configuration

43

public void setDocumentFactory(DocumentFactory documentFactory);

44

public DocumentFactory getDocumentFactory();

45

}

46

```

47

48

**Usage Examples:**

49

50

```java

51

import org.dom4j.io.STAXEventReader;

52

import javax.xml.stream.XMLInputFactory;

53

54

// Read from InputStream

55

STAXEventReader staxReader = new STAXEventReader();

56

Document document = staxReader.readDocument(inputStream);

57

58

// Read from XMLEventReader

59

XMLInputFactory factory = XMLInputFactory.newInstance();

60

XMLEventReader eventReader = factory.createXMLEventReader(inputStream);

61

Document doc = staxReader.readDocument(eventReader);

62

```

63

64

## STAXEventWriter - StAX Event Stream Writing

65

66

STAXEventWriter writes DOM4J documents and nodes to StAX XMLEventWriter streams.

67

68

### Package and Import

69

```java { .api }

70

import org.dom4j.io.STAXEventWriter;

71

import javax.xml.stream.XMLEventWriter;

72

import javax.xml.stream.XMLStreamException;

73

```

74

75

### STAXEventWriter Constructors

76

```java { .api }

77

public class STAXEventWriter {

78

// Constructor with XMLEventWriter

79

public STAXEventWriter(XMLEventWriter xmlEventWriter);

80

}

81

```

82

83

### Writing Methods

84

```java { .api }

85

public class STAXEventWriter {

86

// Write complete documents

87

public void writeDocument(Document document) throws XMLStreamException;

88

89

// Write individual nodes

90

public void writeNode(Node node) throws XMLStreamException;

91

public void writeElement(Element element) throws XMLStreamException;

92

93

// Write open/close element tags

94

public void writeStartElement(Element element) throws XMLStreamException;

95

public void writeEndElement(Element element) throws XMLStreamException;

96

97

// Configuration

98

public XMLEventWriter getXMLEventWriter();

99

}

100

```

101

102

## HTMLWriter - HTML Output Format

103

104

HTMLWriter extends XMLWriter to produce HTML-compliant output with HTML-specific formatting rules.

105

106

### Package and Import

107

```java { .api }

108

import org.dom4j.io.HTMLWriter;

109

import org.dom4j.io.OutputFormat;

110

```

111

112

### HTMLWriter Constructors

113

```java { .api }

114

public class HTMLWriter extends XMLWriter {

115

// Default constructor

116

public HTMLWriter();

117

118

// Writer-based constructors

119

public HTMLWriter(Writer writer);

120

public HTMLWriter(Writer writer, OutputFormat format);

121

122

// OutputStream-based constructors

123

public HTMLWriter(OutputStream out) throws UnsupportedEncodingException;

124

public HTMLWriter(OutputStream out, OutputFormat format) throws UnsupportedEncodingException;

125

}

126

```

127

128

### HTML-specific Features

129

```java { .api }

130

public class HTMLWriter extends XMLWriter {

131

// HTML element handling

132

protected boolean isElementSpaceSensitive(Element element);

133

protected void writeElementContent(Element element) throws IOException;

134

135

// HTML formatting options

136

public void setHtmlMode(boolean htmlMode);

137

public boolean isHtmlMode();

138

}

139

```

140

141

## XMLWriter - Formatted XML Output

142

143

XMLWriter is the primary class for writing DOM4J documents to XML format with configurable formatting options.

144

145

### Package and Import

146

```java { .api }

147

import org.dom4j.io.XMLWriter;

148

import org.dom4j.io.OutputFormat;

149

import java.io.*;

150

```

151

152

### XMLWriter Constructors

153

```java { .api }

154

public class XMLWriter {

155

// Default constructor - writes to System.out

156

public XMLWriter();

157

158

// Writer-based constructors

159

public XMLWriter(Writer writer);

160

public XMLWriter(Writer writer, OutputFormat format);

161

162

// OutputStream-based constructors

163

public XMLWriter(OutputStream out) throws UnsupportedEncodingException;

164

public XMLWriter(OutputStream out, OutputFormat format) throws UnsupportedEncodingException;

165

}

166

```

167

168

### Writing Methods

169

```java { .api }

170

public class XMLWriter {

171

// Write complete documents

172

public void write(Document doc) throws IOException;

173

174

// Write individual nodes

175

public void write(Element element) throws IOException;

176

public void write(Node node) throws IOException;

177

public void write(Attribute attribute) throws IOException;

178

public void write(CDATA cdata) throws IOException;

179

public void write(Comment comment) throws IOException;

180

public void write(Entity entity) throws IOException;

181

public void write(ProcessingInstruction pi) throws IOException;

182

public void write(Text text) throws IOException;

183

184

// Element streaming

185

public void writeOpen(Element element) throws IOException;

186

public void writeClose(Element element) throws IOException;

187

188

// Stream management

189

public void flush() throws IOException;

190

public void close() throws IOException;

191

}

192

```

193

194

### Configuration Methods

195

```java { .api }

196

public class XMLWriter {

197

// Format configuration

198

public OutputFormat getOutputFormat();

199

public void setOutputFormat(OutputFormat outputFormat);

200

201

// Entity reference handling

202

public boolean getResolveEntityRefs();

203

public void setResolveEntityRefs(boolean resolve);

204

}

205

```

206

207

### Using XMLWriter

208

```java { .api }

209

// Basic document writing

210

Document document = createSampleDocument();

211

212

// Write to file with default formatting

213

try (FileWriter fileWriter = new FileWriter("output.xml")) {

214

XMLWriter writer = new XMLWriter(fileWriter);

215

writer.write(document);

216

}

217

218

// Write to string

219

StringWriter stringWriter = new StringWriter();

220

XMLWriter xmlWriter = new XMLWriter(stringWriter);

221

xmlWriter.write(document);

222

String xmlString = stringWriter.toString();

223

224

// Write to output stream with encoding

225

try (FileOutputStream fos = new FileOutputStream("output.xml")) {

226

OutputFormat format = OutputFormat.createPrettyPrint();

227

format.setEncoding("UTF-8");

228

XMLWriter writer = new XMLWriter(fos, format);

229

writer.write(document);

230

}

231

232

// Write individual elements

233

Element rootElement = document.getRootElement();

234

try (PrintWriter pw = new PrintWriter("element.xml")) {

235

XMLWriter writer = new XMLWriter(pw, OutputFormat.createCompactFormat());

236

writer.write(rootElement);

237

}

238

239

// Streaming element writing for large documents

240

try (FileWriter fw = new FileWriter("large.xml")) {

241

XMLWriter writer = new XMLWriter(fw, OutputFormat.createPrettyPrint());

242

243

// Manual document structure

244

writer.writeOpen(DocumentHelper.createElement("catalog"));

245

246

for (Product product : products) {

247

Element productElement = createElement(product);

248

writer.write(productElement);

249

}

250

251

writer.writeClose(DocumentHelper.createElement("catalog"));

252

}

253

```

254

255

## OutputFormat - XML Formatting Configuration

256

257

OutputFormat controls how XML is formatted during output, including indentation, encoding, and various formatting options.

258

259

### Package and Import

260

```java { .api }

261

import org.dom4j.io.OutputFormat;

262

```

263

264

### OutputFormat Factory Methods

265

```java { .api }

266

public class OutputFormat {

267

// Predefined formats

268

public static OutputFormat createPrettyPrint();

269

public static OutputFormat createCompactFormat();

270

271

// Custom format

272

public OutputFormat();

273

public OutputFormat(String indent);

274

public OutputFormat(String indent, boolean newlines);

275

public OutputFormat(String indent, boolean newlines, String encoding);

276

}

277

```

278

279

### Declaration and Encoding Configuration

280

```java { .api }

281

public class OutputFormat {

282

// XML declaration

283

public boolean isSuppressDeclaration();

284

public void setSuppressDeclaration(boolean suppressDeclaration);

285

public boolean isNewLineAfterDeclaration();

286

public void setNewLineAfterDeclaration(boolean newLineAfterDeclaration);

287

288

// Encoding configuration

289

public String getEncoding();

290

public void setEncoding(String encoding);

291

public boolean isOmitEncoding();

292

public void setOmitEncoding(boolean omitEncoding);

293

}

294

```

295

296

### Indentation and Formatting

297

```java { .api }

298

public class OutputFormat {

299

// Indentation

300

public String getIndent();

301

public void setIndent(String indent);

302

public void setIndent(boolean doIndent);

303

304

// Line formatting

305

public boolean isNewlines();

306

public void setNewlines(boolean newlines);

307

public String getLineSeparator();

308

public void setLineSeparator(String separator);

309

310

// Element formatting

311

public boolean isExpandEmptyElements();

312

public void setExpandEmptyElements(boolean expandEmptyElements);

313

}

314

```

315

316

### Text Content Formatting

317

```java { .api }

318

public class OutputFormat {

319

// Text processing

320

public boolean isTrimText();

321

public void setTrimText(boolean trimText);

322

public boolean isPadText();

323

public void setPadText(boolean padText);

324

325

// Attribute formatting

326

public char getAttributeQuoteCharacter();

327

public void setAttributeQuoteCharacter(char quoteChar);

328

}

329

```

330

331

### HTML/XHTML Support

332

```java { .api }

333

public class OutputFormat {

334

// XHTML mode

335

public boolean isXHTML();

336

public void setXHTML(boolean doXHTML);

337

}

338

```

339

340

### Using OutputFormat

341

```java { .api }

342

// Pretty printed XML with indentation

343

OutputFormat prettyFormat = OutputFormat.createPrettyPrint();

344

prettyFormat.setEncoding("UTF-8");

345

prettyFormat.setIndent(" "); // 2-space indentation

346

prettyFormat.setNewLineAfterDeclaration(false);

347

348

// Compact format for minimal size

349

OutputFormat compactFormat = OutputFormat.createCompactFormat();

350

compactFormat.setSuppressDeclaration(true);

351

compactFormat.setTrimText(true);

352

353

// Custom formatting

354

OutputFormat customFormat = new OutputFormat();

355

customFormat.setIndent(true);

356

customFormat.setNewlines(true);

357

customFormat.setLineSeparator("\n");

358

customFormat.setEncoding("ISO-8859-1");

359

customFormat.setExpandEmptyElements(false); // Use <element/> instead of <element></element>

360

customFormat.setAttributeQuoteCharacter('\''); // Use single quotes for attributes

361

362

// XHTML formatting

363

OutputFormat xhtmlFormat = OutputFormat.createPrettyPrint();

364

xhtmlFormat.setXHTML(true);

365

xhtmlFormat.setExpandEmptyElements(false);

366

367

// Text processing configuration

368

OutputFormat textFormat = OutputFormat.createPrettyPrint();

369

textFormat.setTrimText(true); // Remove leading/trailing whitespace

370

textFormat.setPadText(false); // Don't add extra whitespace

371

372

// Use formats with XMLWriter

373

Document document = createDocument();

374

375

try (FileWriter writer = new FileWriter("pretty.xml")) {

376

XMLWriter xmlWriter = new XMLWriter(writer, prettyFormat);

377

xmlWriter.write(document);

378

}

379

380

try (FileWriter writer = new FileWriter("compact.xml")) {

381

XMLWriter xmlWriter = new XMLWriter(writer, compactFormat);

382

xmlWriter.write(document);

383

}

384

```

385

386

## SAXReader - Advanced Parsing Options

387

388

Extended coverage of SAXReader for advanced parsing scenarios beyond basic document creation.

389

390

### Advanced Configuration

391

```java { .api }

392

import org.dom4j.io.SAXReader;

393

import org.xml.sax.XMLReader;

394

import org.xml.sax.helpers.XMLReaderFactory;

395

396

// Custom XMLReader configuration

397

SAXReader reader = new SAXReader();

398

XMLReader xmlReader = reader.getXMLReader();

399

400

// Configure SAX features

401

xmlReader.setFeature("http://xml.org/sax/features/namespaces", true);

402

xmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", false);

403

xmlReader.setFeature("http://xml.org/sax/features/validation", true);

404

405

// Configure SAX properties

406

xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", lexicalHandler);

407

xmlReader.setProperty("http://xml.org/sax/properties/declaration-handler", declHandler);

408

409

// Schema validation

410

xmlReader.setFeature("http://apache.org/xml/features/validation/schema", true);

411

xmlReader.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation",

412

"http://example.com/schema http://example.com/schema.xsd");

413

```

414

415

### Large Document Processing

416

```java { .api }

417

// Memory-efficient parsing for large documents

418

SAXReader reader = new SAXReader();

419

420

// Configure for memory efficiency

421

reader.setValidating(false); // Disable validation for speed

422

reader.setEntityResolver(null); // No external entity resolution

423

424

// Custom document factory for memory optimization

425

reader.setDocumentFactory(new DocumentFactory() {

426

@Override

427

public Element createElement(QName qname) {

428

// Return memory-optimized element implementation

429

return new LightweightElement(qname);

430

}

431

});

432

433

// Parse with progress monitoring

434

class ProgressEntityResolver implements EntityResolver {

435

private long bytesRead = 0;

436

437

@Override

438

public InputSource resolveEntity(String publicId, String systemId) throws IOException {

439

// Monitor parsing progress

440

System.out.println("Processing entity: " + systemId);

441

return null;

442

}

443

}

444

445

reader.setEntityResolver(new ProgressEntityResolver());

446

```

447

448

## HTMLWriter - HTML-Specific Output

449

450

HTMLWriter extends XMLWriter for HTML-specific formatting requirements.

451

452

### Package and Import

453

```java { .api }

454

import org.dom4j.io.HTMLWriter;

455

```

456

457

### Using HTMLWriter

458

```java { .api }

459

// HTML-specific formatting

460

HTMLWriter htmlWriter = new HTMLWriter();

461

462

// HTML formatting automatically handles:

463

// - Empty elements (br, hr, img, etc.)

464

// - Case sensitivity

465

// - Entity encoding for HTML

466

467

Document htmlDocument = createHtmlDocument();

468

try (FileWriter writer = new FileWriter("output.html")) {

469

HTMLWriter htmlOut = new HTMLWriter(writer);

470

htmlOut.write(htmlDocument);

471

}

472

473

// Custom HTML formatting

474

OutputFormat htmlFormat = OutputFormat.createPrettyPrint();

475

htmlFormat.setXHTML(true); // XHTML compatibility

476

htmlFormat.setExpandEmptyElements(false); // <br/> instead of <br></br>

477

478

try (FileWriter writer = new FileWriter("xhtml.html")) {

479

HTMLWriter htmlOut = new HTMLWriter(writer, htmlFormat);

480

htmlOut.write(htmlDocument);

481

}

482

```

483

484

## SAXWriter - Generate SAX Events

485

486

SAXWriter writes DOM4J documents as SAX events, enabling integration with SAX-based processing pipelines.

487

488

### Package and Import

489

```java { .api }

490

import org.dom4j.io.SAXWriter;

491

import org.xml.sax.ContentHandler;

492

import org.xml.sax.helpers.DefaultHandler;

493

```

494

495

### Using SAXWriter

496

```java { .api }

497

// Write DOM4J document as SAX events

498

Document document = createDocument();

499

500

// Custom SAX content handler

501

ContentHandler handler = new DefaultHandler() {

502

@Override

503

public void startElement(String uri, String localName, String qName, Attributes attributes) {

504

System.out.println("Start element: " + qName);

505

}

506

507

@Override

508

public void endElement(String uri, String localName, String qName) {

509

System.out.println("End element: " + qName);

510

}

511

512

@Override

513

public void characters(char[] ch, int start, int length) {

514

String text = new String(ch, start, length).trim();

515

if (!text.isEmpty()) {

516

System.out.println("Text: " + text);

517

}

518

}

519

};

520

521

// Generate SAX events

522

SAXWriter saxWriter = new SAXWriter(handler);

523

saxWriter.write(document);

524

525

// Chain with SAX transformers

526

TransformerFactory factory = TransformerFactory.newInstance();

527

Templates template = factory.newTemplates(new StreamSource("transform.xsl"));

528

Transformer transformer = template.newTransformer();

529

530

SAXResult result = new SAXResult(handler);

531

SAXWriter chainedWriter = new SAXWriter(transformer);

532

chainedWriter.write(document);

533

```

534

535

## Dispatch Handlers for Event-Driven Processing

536

537

DOM4J provides dispatch handler classes for event-driven processing of large XML documents with memory efficiency.

538

539

### DispatchHandler - Element Event Processing

540

```java { .api }

541

import org.dom4j.io.DispatchHandler;

542

import org.dom4j.ElementHandler;

543

import org.dom4j.ElementPath;

544

545

public class DispatchHandler extends SAXContentHandler {

546

// Constructor

547

public DispatchHandler();

548

549

// Handler registration

550

public void addHandler(String path, ElementHandler handler);

551

public void removeHandler(String path);

552

public boolean containsHandler(String path);

553

554

// Handler access

555

public ElementHandler getHandler(String path);

556

public int getActiveHandlerCount();

557

558

// Path-based handlers

559

public void setDefaultHandler(ElementHandler handler);

560

public ElementHandler getDefaultHandler();

561

}

562

```

563

564

### PruningDispatchHandler - Memory-Efficient Processing

565

```java { .api }

566

import org.dom4j.io.PruningDispatchHandler;

567

568

public class PruningDispatchHandler extends DispatchHandler {

569

// Automatically prunes elements when no handlers are active

570

// Useful for processing large documents with minimal memory usage

571

572

// Constructor

573

public PruningDispatchHandler();

574

575

// Inherited methods from DispatchHandler

576

// Automatically detaches processed elements to save memory

577

}

578

```

579

580

**Usage Examples:**

581

582

```java

583

import org.dom4j.io.PruningDispatchHandler;

584

import org.dom4j.ElementHandler;

585

import org.dom4j.ElementPath;

586

587

// Memory-efficient processing of large documents

588

PruningDispatchHandler handler = new PruningDispatchHandler();

589

590

// Process specific elements and prune them

591

handler.addHandler("/catalog/product", new ElementHandler() {

592

public void onStart(ElementPath path) {

593

Element product = path.getCurrent();

594

System.out.println("Processing product: " + product.attributeValue("id"));

595

}

596

597

public void onEnd(ElementPath path) {

598

Element product = path.getCurrent();

599

// Process product data

600

processProduct(product);

601

// Element will be automatically pruned after this handler

602

}

603

});

604

605

// Use with SAXReader for large document processing

606

SAXReader reader = new SAXReader();

607

reader.setContentHandler(handler);

608

reader.read(largeXmlFile); // Processes with minimal memory usage

609

```

610

611

### ElementStack - Element Path Tracking

612

```java { .api }

613

import org.dom4j.io.ElementStack;

614

615

public class ElementStack {

616

// Constructor

617

public ElementStack();

618

619

// Stack operations

620

public void pushElement(Element element);

621

public Element popElement();

622

public Element peekElement();

623

624

// Path access

625

public ElementPath getPath();

626

public String getPathString();

627

public int getDepth();

628

629

// Path queries

630

public boolean matches(String pathPattern);

631

public Element getElementAtDepth(int depth);

632

}

633

```

634

635

## DOM Interoperability

636

637

DOM4J provides classes for converting between DOM4J and W3C DOM representations.

638

639

### DOMReader - W3C DOM to DOM4J

640

```java { .api }

641

import org.dom4j.io.DOMReader;

642

import org.w3c.dom.Document as W3CDocument;

643

644

// Convert W3C DOM to DOM4J

645

DOMReader domReader = new DOMReader();

646

647

// From W3C Document

648

W3CDocument w3cDocument = getW3CDocument();

649

Document dom4jDocument = domReader.read(w3cDocument);

650

651

// From W3C Element

652

org.w3c.dom.Element w3cElement = getW3CElement();

653

Document fragmentDoc = domReader.read(w3cElement);

654

```

655

656

### DOMWriter - DOM4J to W3C DOM

657

```java { .api }

658

import org.dom4j.io.DOMWriter;

659

import javax.xml.parsers.DocumentBuilderFactory;

660

661

// Convert DOM4J to W3C DOM

662

DOMWriter domWriter = new DOMWriter();

663

664

Document dom4jDocument = createDocument();

665

666

// Write to W3C Document

667

W3CDocument w3cDocument = domWriter.write(dom4jDocument);

668

669

// Write to existing W3C Document

670

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

671

factory.setNamespaceAware(true);

672

W3CDocument targetDocument = factory.newDocumentBuilder().newDocument();

673

W3CDocument result = domWriter.write(dom4jDocument, targetDocument);

674

675

// Write element to W3C Document

676

Element dom4jElement = dom4jDocument.getRootElement();

677

org.w3c.dom.Element w3cElement = domWriter.write(dom4jElement, targetDocument);

678

```

679

680

## JAXP Integration

681

682

DOM4J provides JAXP (Java API for XML Processing) integration classes for seamless interoperability with other XML processing APIs.

683

684

### DocumentInputSource - DOM4J to SAX InputSource

685

```java { .api }

686

import org.dom4j.io.DocumentInputSource;

687

import org.xml.sax.InputSource;

688

689

public class DocumentInputSource extends InputSource {

690

// Constructors

691

public DocumentInputSource();

692

public DocumentInputSource(Document document);

693

694

// Document access

695

public Document getDocument();

696

public void setDocument(Document document);

697

698

// InputSource methods (inherited)

699

public Reader getCharacterStream();

700

public void setCharacterStream(Reader characterStream);

701

}

702

```

703

704

### DocumentResult - JAXP Result for DOM4J

705

```java { .api }

706

import org.dom4j.io.DocumentResult;

707

import javax.xml.transform.Result;

708

709

public class DocumentResult implements Result {

710

// Constructors

711

public DocumentResult();

712

public DocumentResult(DocumentFactory factory);

713

714

// Result interface implementation

715

public void setSystemId(String systemId);

716

public String getSystemId();

717

718

// DOM4J specific methods

719

public Document getDocument();

720

public void setDocumentFactory(DocumentFactory factory);

721

public DocumentFactory getDocumentFactory();

722

}

723

```

724

725

### DocumentSource - JAXP Source for DOM4J

726

```java { .api }

727

import org.dom4j.io.DocumentSource;

728

import javax.xml.transform.Source;

729

730

public class DocumentSource implements Source {

731

// Constructors

732

public DocumentSource(Document document);

733

public DocumentSource(Node node);

734

735

// Source interface implementation

736

public void setSystemId(String systemId);

737

public String getSystemId();

738

739

// DOM4J specific methods

740

public Document getDocument();

741

public Node getNode();

742

}

743

```

744

745

## XML Pull Parser (XPP) Integration

746

747

DOM4J supports XML Pull Parser for efficient streaming XML processing.

748

749

### XPP3Reader - XPP to DOM4J

750

```java { .api }

751

import org.dom4j.io.XPP3Reader;

752

import org.xmlpull.v1.XmlPullParser;

753

import org.xmlpull.v1.XmlPullParserFactory;

754

755

// Create pull parser

756

XmlPullParserFactory factory = XmlPullParserFactory.newInstance();

757

factory.setNamespaceAware(true);

758

XmlPullParser parser = factory.newPullParser();

759

parser.setInput(new FileReader("input.xml"));

760

761

// Read with XPP3Reader

762

XPP3Reader xppReader = new XPP3Reader();

763

Document document = xppReader.read(parser);

764

765

// Custom document factory

766

xppReader.setDocumentFactory(customFactory);

767

Document customDoc = xppReader.read(parser);

768

```

769

770

## Advanced I/O Patterns

771

772

### Streaming Large Documents

773

```java { .api }

774

// Process large XML documents incrementally

775

public class StreamingXMLProcessor {

776

private final XMLWriter writer;

777

private final OutputFormat format;

778

779

public StreamingXMLProcessor(OutputStream output) throws IOException {

780

this.format = OutputFormat.createCompactFormat();

781

this.writer = new XMLWriter(output, format);

782

}

783

784

public void processLargeDocument(InputStream input) throws Exception {

785

SAXReader reader = new SAXReader();

786

787

// Custom content handler for streaming processing

788

reader.setContentHandler(new DefaultHandler() {

789

private Element currentElement;

790

private boolean inTargetElement = false;

791

792

@Override

793

public void startElement(String uri, String localName, String qName, Attributes attributes) {

794

if ("target".equals(localName)) {

795

inTargetElement = true;

796

currentElement = DocumentHelper.createElement(qName);

797

// Copy attributes

798

for (int i = 0; i < attributes.getLength(); i++) {

799

currentElement.addAttribute(attributes.getQName(i), attributes.getValue(i));

800

}

801

}

802

}

803

804

@Override

805

public void characters(char[] ch, int start, int length) {

806

if (inTargetElement && currentElement != null) {

807

currentElement.addText(new String(ch, start, length));

808

}

809

}

810

811

@Override

812

public void endElement(String uri, String localName, String qName) throws SAXException {

813

if ("target".equals(localName) && currentElement != null) {

814

try {

815

// Process and write element immediately

816

processElement(currentElement);

817

writer.write(currentElement);

818

writer.flush();

819

} catch (IOException e) {

820

throw new SAXException("Write error", e);

821

} finally {

822

currentElement = null;

823

inTargetElement = false;

824

}

825

}

826

}

827

});

828

829

reader.read(input);

830

}

831

832

private void processElement(Element element) {

833

// Custom processing logic

834

String processed = element.getText().toUpperCase();

835

element.setText(processed);

836

}

837

838

public void close() throws IOException {

839

writer.close();

840

}

841

}

842

```

843

844

### Parallel Document Processing

845

```java { .api }

846

// Process multiple documents concurrently

847

public class ParallelXMLProcessor {

848

private final ExecutorService executor;

849

private final OutputFormat format;

850

851

public ParallelXMLProcessor(int threads) {

852

this.executor = Executors.newFixedThreadPool(threads);

853

this.format = OutputFormat.createPrettyPrint();

854

}

855

856

public CompletableFuture<Void> processDocumentAsync(File inputFile, File outputFile) {

857

return CompletableFuture.runAsync(() -> {

858

try {

859

SAXReader reader = new SAXReader();

860

Document document = reader.read(inputFile);

861

862

// Process document

863

transformDocument(document);

864

865

// Write result

866

try (FileWriter writer = new FileWriter(outputFile)) {

867

XMLWriter xmlWriter = new XMLWriter(writer, format);

868

xmlWriter.write(document);

869

}

870

} catch (Exception e) {

871

throw new RuntimeException("Processing failed for " + inputFile, e);

872

}

873

}, executor);

874

}

875

876

public void processMultipleDocuments(List<File> inputFiles, File outputDirectory) {

877

List<CompletableFuture<Void>> futures = inputFiles.stream()

878

.map(file -> {

879

File outputFile = new File(outputDirectory, file.getName());

880

return processDocumentAsync(file, outputFile);

881

})

882

.collect(Collectors.toList());

883

884

// Wait for all to complete

885

CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

886

}

887

888

private void transformDocument(Document document) {

889

// Custom transformation logic

890

List<Element> elements = document.selectNodes("//element");

891

elements.forEach(element -> element.addAttribute("processed", "true"));

892

}

893

894

public void shutdown() {

895

executor.shutdown();

896

}

897

}

898

```

899

900

### Memory-Efficient Processing

901

```java { .api }

902

// Custom document factory for memory optimization

903

public class MemoryEfficientDocumentFactory extends DocumentFactory {

904

@Override

905

public Element createElement(QName qname) {

906

return new MemoryEfficientElement(qname);

907

}

908

909

@Override

910

public Attribute createAttribute(Element owner, QName qname, String value) {

911

return new MemoryEfficientAttribute(qname, value);

912

}

913

}

914

915

// Lightweight element implementation

916

class MemoryEfficientElement extends DefaultElement {

917

public MemoryEfficientElement(QName qname) {

918

super(qname);

919

}

920

921

// Override methods to reduce memory usage

922

@Override

923

protected List<Node> createContentList() {

924

// Use memory-efficient list implementation

925

return new ArrayList<>(4); // Small initial capacity

926

}

927

928

@Override

929

protected List<Attribute> createAttributeList() {

930

return new ArrayList<>(2); // Most elements have few attributes

931

}

932

}

933

934

// Use memory-efficient factory

935

SAXReader reader = new SAXReader();

936

reader.setDocumentFactory(new MemoryEfficientDocumentFactory());

937

938

Document document = reader.read(largeXmlFile);

939

// Document uses less memory due to optimized implementations

940

```

941

942

DOM4J's I/O capabilities provide comprehensive support for reading and writing XML documents with fine-grained control over formatting, performance, and integration with other XML processing APIs. The flexible architecture allows for both simple operations and complex enterprise XML processing scenarios.