DomTrip Examples

Explore practical examples of using DomTrip for various XML editing scenarios.

Basic XML Editing

Simple Element Modification

String xml =
        """
    <config>
        <database>
            <host>localhost</host>
            <port>5432</port>
        </database>
    </config>
    """;

Document doc = Document.of(xml);
Editor editor = new Editor(doc);

// Find and update the host
Element host = editor.root().descendant("host").orElseThrow();
editor.setTextContent(host, "production-db.example.com");

// Find and update the port
Element port = editor.root().descendant("port").orElseThrow();
editor.setTextContent(port, "5433");

String result = editor.toXml();}

Adding New Elements

Document doc = Document.of("<project></project>");
Editor editor = new Editor(doc);

Element root = editor.root();

// Add dependencies section
Element dependencies = editor.addElement(root, "dependencies");

// Add a dependency with multiple children
Element dependency = editor.addElement(dependencies, "dependency");
editor.addElement(dependency, "groupId", "junit");
editor.addElement(dependency, "artifactId", "junit");
editor.addElement(dependency, "version", "4.13.2");
editor.addElement(dependency, "scope", "test");

String result = editor.toXml();}

Maven POM Editing

The DomTrip Maven extension provides specialized functionality for working with Maven POM files.

Basic POM Creation with Maven Extension

// Create a new POM with Maven-aware ordering
PomEditor editor = new PomEditor();
editor.createMavenDocument("project");
Element root = editor.root();

// Add elements - they'll be automatically ordered
editor.insertMavenElement(root, MODEL_VERSION, "4.0.0");
editor.insertMavenElement(root, GROUP_ID, "com.example");
editor.insertMavenElement(root, ARTIFACT_ID, "my-project");
editor.insertMavenElement(root, VERSION, "1.0.0");
editor.insertMavenElement(root, NAME, "My Project");

String result = editor.toXml();

Adding Dependencies with Maven Extension

PomEditor editor = new PomEditor();
editor.createMavenDocument("project");
Element root = editor.root();

// Add dependencies with proper structure
Element dependencies = editor.insertMavenElement(root, DEPENDENCIES);
editor.addDependency(dependencies, "org.junit.jupiter", "junit-jupiter", "5.9.2");

// Add scope to the dependency
Element junitDep = editor.findChildElement(dependencies, DEPENDENCY);
editor.insertMavenElement(junitDep, SCOPE, "test");

Adding Plugins with Maven Extension

PomEditor editor = new PomEditor();
editor.createMavenDocument("project");
Element root = editor.root();

// Add build plugins with configuration
Element build = editor.insertMavenElement(root, BUILD);
Element plugins = editor.insertMavenElement(build, PLUGINS);

Element compilerPlugin =
        editor.addPlugin(plugins, "org.apache.maven.plugins", "maven-compiler-plugin", "3.11.0");
Element config = editor.insertMavenElement(compilerPlugin, CONFIGURATION);
editor.addElement(config, "source", "17");
editor.addElement(config, "target", "17");

Maven Settings Editing

The SettingsEditor provides specialized functionality for working with Maven settings.xml files.

Basic Settings Creation

// Create a new settings document
SettingsEditor editor = new SettingsEditor();
editor.createSettingsDocument();
Element root = editor.root();

// Add elements with automatic ordering
editor.insertSettingsElement(root, LOCAL_REPOSITORY, "/custom/repo");
editor.insertSettingsElement(root, OFFLINE, "false");

String result = editor.toXml();

Adding Servers

SettingsEditor editor = new SettingsEditor();
editor.createSettingsDocument();
Element root = editor.root();

// Add servers with convenience methods
Element servers = editor.insertSettingsElement(root, SERVERS);
editor.addServer(servers, "my-server", "username", "password");
editor.addServer(servers, "nexus", "admin", "secret123");

String result = editor.toXml();

Adding Mirrors

SettingsEditor editor = new SettingsEditor();
editor.createSettingsDocument();
Element root = editor.root();

// Add mirrors
Element mirrors = editor.insertSettingsElement(root, MIRRORS);
editor.addMirror(mirrors, "central-mirror", "Central Mirror", "https://repo1.maven.org/maven2", "central");
editor.addMirror(
        mirrors, "nexus-mirror", "Nexus Mirror", "https://nexus.example.com/repository/maven-public/", "*");

String result = editor.toXml();

Adding Profiles

SettingsEditor editor = new SettingsEditor();
editor.createSettingsDocument();
Element root = editor.root();

// Add profiles with properties
Element profiles = editor.insertSettingsElement(root, PROFILES);
Element profile = editor.addProfile(profiles, "development");

Element properties = editor.insertSettingsElement(profile, PROPERTIES);
editor.addProperty(properties, "maven.compiler.source", "17");
editor.addProperty(properties, "maven.compiler.target", "17");
editor.addProperty(properties, "env", "dev");

String result = editor.toXml();

Maven Extensions Editing

The ExtensionsEditor provides functionality for working with Maven extensions.xml files.

Basic Extensions Creation

// Create a new extensions document
ExtensionsEditor editor = new ExtensionsEditor();
editor.createExtensionsDocument();
Element root = editor.root();

// Add extensions with convenience methods
editor.addExtension(root, "org.apache.maven.wagon", "wagon-ssh", "3.5.1");
editor.addExtension(root, "io.takari.maven", "takari-smart-builder", "0.6.1");

String result = editor.toXml();

Adding Extensions

ExtensionsEditor editor = new ExtensionsEditor();
editor.createExtensionsDocument();
Element root = editor.root();

// Add various types of extensions
editor.addExtension(root, "org.apache.maven.wagon", "wagon-ssh", "3.5.1");
editor.addExtension(root, "io.takari.maven", "takari-smart-builder", "0.6.1");
editor.addExtension(root, "org.eclipse.tycho", "tycho-maven-plugin", "3.0.4", null, "maven-plugin");

String result = editor.toXml();

Maven Toolchains Editing

The ToolchainsEditor provides functionality for working with Maven toolchains.xml files.

Basic Toolchains Creation

// Create a new toolchains document
ToolchainsEditor editor = new ToolchainsEditor();
editor.createToolchainsDocument();
Element root = editor.root();

// Add JDK toolchains with convenience methods
editor.addJdkToolchain(root, "17", "openjdk", "/path/to/jdk/17");
editor.addJdkToolchain(root, "11", "adoptium", "/path/to/jdk/11");

String result = editor.toXml();

Adding JDK Toolchains

ToolchainsEditor editor = new ToolchainsEditor();
editor.createToolchainsDocument();
Element root = editor.root();

// Add multiple JDK toolchains
editor.addJdkToolchain(root, "17", "openjdk", "/path/to/jdk/17");
editor.addJdkToolchain(root, "11", "adoptium", "/path/to/jdk/11");
editor.addJdkToolchain(root, "1.8", "oracle", "/path/to/jdk/8");

String result = editor.toXml();

Adding Various Toolchains

ToolchainsEditor editor = new ToolchainsEditor();
editor.createToolchainsDocument();
Element root = editor.root();

// Add JDK toolchains
editor.addJdkToolchain(root, "17", "openjdk", "/path/to/jdk/17");

// Add NetBeans toolchain
editor.addNetBeansToolchain(root, "12.0", "/path/to/netbeans");

// Add custom toolchain
Element customToolchain = editor.addToolchain(root, "protobuf");
editor.addProvides(customToolchain, "version", "3.21.0");
editor.addConfiguration(customToolchain, "protocExecutable", "/usr/local/bin/protoc");

String result = editor.toXml();

Core Library Examples

For comparison, here are examples using the core DomTrip library:

Adding Dependencies (Core Library)

String pomXml =
        """
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.example</groupId>
        <artifactId>my-app</artifactId>
        <version>1.0.0</version>
    </project>
    """;

Document doc = Document.of(pomXml);
Editor editor = new Editor(doc);
Element project = editor.root();

// Add dependencies section if it doesn't exist
Element dependencies = project.descendant("dependencies").orElse(null);
if (dependencies == null) {
    dependencies = editor.addElement(project, "dependencies");
}

// Add Spring Boot starter
Element springDep = editor.addElement(dependencies, "dependency");
editor.addElement(springDep, "groupId", "org.springframework.boot");
editor.addElement(springDep, "artifactId", "spring-boot-starter-web");
editor.addElement(springDep, "version", "3.2.0");

String result = editor.toXml();}

Updating Version (Core Library)

String pomContent = createMavenPomXml();
Document doc = Document.of(pomContent);
Editor editor = new Editor(doc);

// Update project version
Element version = editor.root().descendant("version").orElse(null);
if (version != null) {
    editor.setTextContent(version, "2.0.0");
}

// Update parent version if exists
Element parent = editor.root().descendant("parent").orElse(null);
if (parent != null) {
    Element parentVersion = parent.descendant("version").orElse(null);
    if (parentVersion != null) {
        editor.setTextContent(parentVersion, "2.1.0");
    }
}}

Configuration File Editing

Spring Configuration

String springConfig =
        """
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans">
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
            <property name="driverClassName" value="org.postgresql.Driver"/>
            <property name="url" value="jdbc:postgresql://localhost:5432/mydb"/>
        </bean>
    </beans>
    """;

Document doc = Document.of(springConfig);
Editor editor = new Editor(doc);

// Find the dataSource bean
Element dataSource = editor.root()
        .descendants()
        .filter(e -> "bean".equals(e.name()) && "dataSource".equals(e.attribute("id")))
        .findFirst()
        .orElseThrow();

// Update the URL property
Element urlProperty = dataSource
        .children()
        .filter(e -> "property".equals(e.name()) && "url".equals(e.attribute("name")))
        .findFirst()
        .orElseThrow();

editor.setAttribute(urlProperty, "value", "jdbc:postgresql://prod-db:5432/mydb");

// Add new property
Element newProperty = editor.addElement(dataSource, "property");
editor.setAttribute(newProperty, "name", "maxActive");
editor.setAttribute(newProperty, "value", "100");

Advanced Features

Working with Namespaces

String xmlWithNamespaces =
        """
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <modelVersion>4.0.0</modelVersion>
    </project>
    """;

Document doc = Document.of(xmlWithNamespaces);
Editor editor = new Editor(doc);

// Add element with namespace
Element project = editor.root();
Element build = editor.addElement(project, "build");
Element plugins = editor.addElement(build, "plugins");

// Elements inherit the default namespace automatically
Element plugin = editor.addElement(plugins, "plugin");
editor.addElement(plugin, "groupId", "org.apache.maven.plugins");
editor.addElement(plugin, "artifactId", "maven-compiler-plugin");

Using Builder Patterns

// Create elements using factory methods (simplified builder pattern)
Element dependency = Element.of("dependency");
dependency.addNode(Element.text("groupId", "org.junit.jupiter"));
dependency.addNode(Element.text("artifactId", "junit-jupiter"));
dependency.addNode(Element.text("version", "5.9.2"));
dependency.addNode(Element.text("scope", "test"));

// Add to existing document
String pomXml = createMavenPomXml();
Document doc = Document.of(pomXml);
Editor editor = new Editor(doc);

Element dependencies = editor.root().descendant("dependencies").orElse(null);
if (dependencies == null) {
    dependencies = editor.addElement(editor.root(), "dependencies");
}
dependencies.addNode(dependency);

Attribute Manipulation

String xmlContent = createConfigXml();
Document doc = Document.of(xmlContent);
Editor editor = new Editor(doc);

// Set attributes
Element element = editor.root().descendant("database").orElseThrow();
editor.setAttribute(element, "scope", "test");
editor.setAttribute(element, "optional", "true");

// Remove attributes
editor.removeAttribute(element, "scope");

// Check if attribute exists
if (element.hasAttribute("optional")) {
    String value = element.attribute("optional");
    System.out.println("Optional: " + value);
}

Error Handling

try {
    String xmlContent = createConfigXml();
    Document doc = Document.of(xmlContent);
    Editor editor = new Editor(doc);

    // Safe element finding
    Element element = editor.root().descendant("nonexistent").orElse(null);
    if (element == null) {
        System.out.println("Element not found");
        return;
    }

    // Modify element
    editor.setTextContent(element, "new value");

} catch (Exception e) {
    System.err.println("Unexpected error: " + e.getMessage());
}

Best Practices

1. Always Use Optional for Safe Navigation

String xml = createMavenPomXml();
Document doc = Document.of(xml);
Editor editor = new Editor(doc);

editor.root()
        .descendant("dependencies")
        .map(deps -> editor.addElement(deps, "dependency"))
        .ifPresent(dep -> {
            editor.addElement(dep, "groupId", "org.example");
            editor.addElement(dep, "artifactId", "example-lib");
        });

2. Preserve Original Formatting

String xml = createConfigXml();
Document doc = Document.of(xml);
Editor editor = new Editor(doc);

// DomTrip automatically preserves formatting
// No special configuration needed
String result = editor.toXml(); // Maintains original indentation and style

Next Steps

Core Library

Maven Extension