Migration Guide
This guide helps you migrate from other XML libraries to DomTrip. We cover the most common migration scenarios and provide side-by-side examples.
From DOM4J
DOM4J is one of the most popular XML libraries for Java. Here's how to migrate common patterns:
Document Loading
// DomTrip equivalent of DOM4J SAXReader.read()
String xml = createTestXml("root");
Document document = Document.of(xml);
Editor editor = new Editor(document);
Assertions.assertNotNull(editor);
Element Navigation
// DomTrip equivalent of DOM4J element navigation
String xml = createTestXml("root");
Document document = Document.of(xml);
Editor editor = new Editor(document);
Element root = editor.root();
Optional<Element> child = root.childElement("child");
Stream<Element> children = root.childElements("item");
Adding Elements
// DomTrip equivalent of DOM4J addElement()
String xml = createMavenPomXml();
Document document = Document.of(xml);
Editor editor = new Editor(document);
Element parent = editor.root().descendant("dependencies").orElseThrow();
Element dependency = editor.addElement(parent, "dependency");
editor.addElement(dependency, "groupId", "junit");
editor.addElement(dependency, "artifactId", "junit");
Attribute Handling
// DomTrip equivalent of DOM4J attribute handling
String xml = createTestXml("element");
Document document = Document.of(xml);
Editor editor = new Editor(document);
Element element = editor.root();
editor.setAttribute(element, "scope", "test");
String scope = element.attribute("scope");
Serialization
// DomTrip equivalent of DOM4J serialization
String xml = createTestXml("root");
Document document = Document.of(xml);
Editor editor = new Editor(document);
String result = editor.toXml(); // Preserves original formatting
String prettyXml = editor.toXml(DomTripConfig.prettyPrint());
From JDOM
JDOM has a simpler API than DOM4J but similar concepts:
Document Loading
// DomTrip equivalent of JDOM SAXBuilder.build()
String xml = createTestXml("root");
Document document = Document.of(xml);
Editor editor = new Editor(document);
Assertions.assertNotNull(editor);
Element Operations
// DomTrip equivalent of JDOM element operations
String xml = createTestXml("root");
Document document = Document.of(xml);
Editor editor = new Editor(document);
Element root = editor.root();
Optional<Element> child = root.childElement("child");
Stream<Element> children = root.childElements("item");
// Add new element
Element newElement = editor.addElement(root, "newChild", "content");
Text Content
// DomTrip equivalent of JDOM text content handling
String xml = createTestXml("element");
Document document = Document.of(xml);
Editor editor = new Editor(document);
Element element = editor.root();
editor.setTextContent(element, "new content");
String content = element.textContent();
From Java DOM
The built-in Java DOM API is verbose but powerful:
Document Loading
// DomTrip equivalent of Java DOM document loading
String xml = createTestXml("root");
Document document = Document.of(xml);
Editor editor = new Editor(document);
Assertions.assertNotNull(editor);
Element Navigation
// DomTrip equivalent of Java DOM element navigation
String xml = createTestXml("root");
Document document = Document.of(xml);
Editor editor = new Editor(document);
Element root = editor.root();
Optional<Element> child = root.childElement("child");
Creating Elements
// DomTrip equivalent of Java DOM element creation
String xml = createTestXml("parent");
Document document = Document.of(xml);
Editor editor = new Editor(document);
Element parent = editor.root();
Element newElement = editor.addElement(parent, "newChild", "content");
Attributes
// DomTrip equivalent of Java DOM attribute handling
String xml = createTestXml("element");
Document document = Document.of(xml);
Editor editor = new Editor(document);
Element element = editor.root();
editor.setAttribute(element, "scope", "test");
String scope = element.attribute("scope");
From Jackson XML
Jackson XML is primarily for object mapping, but here are equivalent operations:
Simple Parsing
// DomTrip equivalent of Jackson XML parsing
String xml = createTestXml("root");
Document document = Document.of(xml);
Editor editor = new Editor(document);
Element root = editor.root();
Optional<Element> child = root.childElement("child");
Object Mapping vs Manual Construction
// DomTrip equivalent of Jackson XML object mapping
Element dependency = Element.of("dependency");
dependency.addChild(Element.text("groupId", "junit"));
dependency.addChild(Element.text("artifactId", "junit"));
dependency.addChild(Element.text("version", "4.13.2"));
String xml = dependency.toXml();
Common Migration Patterns
1. Error Handling
// DomTrip provides consistent exception handling
try {
String xml = createTestXml("root");
Document document = Document.of(xml);
Editor editor = new Editor(document);
Assertions.assertNotNull(editor);
} catch (Exception e) {
// Handle parsing error
System.err.println("Failed to parse: " + e.getMessage());
}
2. Namespace Handling
// DomTrip equivalent of DOM4J namespace handling
String xml = createSoapXml();
Document document = Document.of(xml);
Editor editor = new Editor(document);
Element root = editor.root();
// Check if root itself is the Envelope element
assertEquals("Envelope", root.localName());
assertEquals("http://schemas.xmlsoap.org/soap/envelope/", root.namespaceURI());
3. XPath Queries
// DomTrip uses Stream-based filtering instead of XPath
String xml = createMavenPomXml();
Document document = Document.of(xml);
Editor editor = new Editor(document);
Element root = editor.root();
Stream<Element> nodes = root.descendants()
.filter(el -> "dependency".equals(el.name()))
.filter(el -> "test".equals(el.attribute("scope")));
Breaking Changes in Recent Versions
PomEditor Sub-Object API (v1.0.0+)
The PomEditor convenience methods have been moved to sub-object APIs for better organization:
Migration:
// OLD: Direct methods on PomEditor
editor.addDependency(depsElement, "junit", "junit", "4.13.2");
editor.addPlugin(pluginsElement, "org.apache.maven.plugins", "maven-compiler-plugin", "3.11.0");
editor.addModule(modulesElement, "core");
editor.addProperty(propsElement, "java.version", "17");
// NEW: Sub-object APIs
editor.dependencies().addDependency(depsElement, "junit", "junit", "4.13.2");
editor.plugins().addPlugin(pluginsElement, "org.apache.maven.plugins", "maven-compiler-plugin", "3.11.0");
editor.subprojects().addModule(modulesElement, "core");
editor.properties().addProperty(propsElement, "java.version", "17");
New capabilities added in 1.0.0:
editor.dependencies()— CRUD, exclusion management (addExclusion,deleteExclusion,hasExclusion)editor.plugins()— Plugin CRUD and pluginManagementeditor.parent()—setParent(),updateParent(),deleteParent()editor.profiles()—findProfile(),hasProfile()Coordinatesclass for type-safe artifact coordinate handling
Element Navigation Rename (v0.5.0+)
Method names were renamed for clarity:
Migration:
// OLD: Element child navigation
element.child("name"); // ambiguous: child node or child element?
element.children("dependency"); // ambiguous
// NEW: Explicit element navigation
element.childElement("name"); // clearly an element
element.childElements("dependency"); // clearly elements
// OLD: ContainerNode node access
container.nodeAt(0);
container.nodeCount();
// NEW: ContainerNode child access
container.child(0);
container.childCount();
New ContainerNode methods added in 0.6.0:
insertChildBefore(referenceNode, newNode)— insert before a specific childinsertChildAfter(referenceNode, newNode)— insert after a specific childfirstChild()— returnsOptionalof first childlastChild()— returnsOptionalof last childreplaceChild(existingNode, replacementNode)— replace a child node
Whitespace API Simplification (v0.1.1+)
The whitespace handling API has been simplified for better maintainability:
Removed Methods:
Node.followingWhitespace()andNode.followingWhitespace(String)Element.innerFollowingWhitespace()andElement.innerFollowingWhitespace(String)
Migration Strategy:
// OLD: Setting whitespace after a node
node.followingWhitespace("\n ");
// NEW: Set whitespace before the next node instead
nextNode.precedingWhitespace("\n ");
// OLD: Setting whitespace after opening tag
element.innerFollowingWhitespace("\n ");
// NEW: Set whitespace before first child instead
firstChild.precedingWhitespace("\n ");
Rationale: The simplified model eliminates redundant whitespace storage where the same whitespace was stored in multiple places. This reduces memory usage and eliminates synchronization issues.
Migration Checklist
Before Migration
- [ ] Identify all XML processing code in your application
- [ ] Document current XML formatting requirements
- [ ] Create test cases for existing functionality
- [ ] Note any XPath usage (DomTrip doesn't support XPath)
During Migration
- [ ] Replace library imports
- [ ] Update document loading code
- [ ] Convert element navigation to DomTrip patterns
- [ ] Update attribute handling
- [ ] Replace serialization code
- [ ] Handle namespace operations
- [ ] Update exception handling
After Migration
- [ ] Run all existing tests
- [ ] Verify XML output formatting
- [ ] Check performance impact
- [ ] Update documentation
- [ ] Train team on new API patterns
Performance Considerations
Memory Usage
// DomTrip includes formatting metadata (~1.3x base size)
String xml = createTestXml("root");
Document document = Document.of(xml);
Editor editor = new Editor(document);
// Memory: ~1.3x base size
Processing Speed
- Parsing: DomTrip is ~15% slower due to metadata collection
- Navigation: Similar performance to other DOM libraries
- Serialization: Faster for unmodified content, slower for heavily modified content
Gradual Migration Strategy
Phase 1: New Code
Start using DomTrip for all new XML processing code:
// Phase 1: Use DomTrip for new features
String pomXml = createMavenPomXml();
Document doc = Document.of(pomXml);
Editor editor = new Editor(doc);
// DomTrip operations here
Phase 2: Critical Paths
Migrate code that requires formatting preservation:
// Phase 2: Migrate formatting-critical code to DomTrip
String configXml = createConfigXml();
Document doc = Document.of(configXml);
Editor editor = new Editor(doc);
// Lossless editing operations here
Phase 3: Complete Migration
Replace remaining XML processing code:
// Phase 3: Migrate data extraction code
String xml = createTestXml("root");
Document document = Document.of(xml);
Editor editor = new Editor(document);
// Data extraction operations here
Getting Help
If you encounter issues during migration: