Skip to content

jaschenk/dataforge-library

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DataForge

A pure Java 25 library for processing XML and JSON with YAML-driven dynamic validation.

Zero external dependencies. Hand-written parsers. Modern Java features.


Features

  • Unified Data Model — Parse XML or JSON into a single tree structure (DataNode)
  • Hand-Written Parsers — Custom recursive descent parsers for XML, JSON, and YAML (no external libraries)
  • Get/Set by Tag Name — Retrieve or update values anywhere in the tree by tag name
  • Dot-Notation Path Access — Navigate nested structures with person.address.city syntax
  • Deep Search — Find all nodes matching a tag name or predicate across the entire tree
  • Tree Manipulation — Add, remove, clone nodes programmatically
  • Format Conversion — Convert XML to JSON and vice versa
  • YAML-Driven Validation — Define validation rules in YAML, apply them dynamically
  • Java 25 Features — Records, sealed interfaces, pattern matching, switch expressions, text blocks, SequencedCollections

Quick Start

import io.dataforge.DataForge;

// Parse XML (auto-detected)
var doc = DataForge.parse("<user><name>Alice</name><age>30</age></user>");

// Get value by tag name (deep search)
String name = doc.getValueByTag("name").orElse("unknown");

// Set value by tag name
doc.setValueByTag("age", "31");

// Get value by dot-notation path
String city = doc.getValueByPath("address.city").orElse("?");

// Convert to JSON
String json = doc.toJson();

// Validate with YAML rules
String yaml = """
    rules:
      name:
        required: true
        type: string
        minLength: 1
      age:
        type: integer
        min: 0
        max: 150
    """;
var result = doc.validate(yaml);
if (!result.isValid()) {
    System.out.println(result.report());
}

API Reference

Parsing

// Auto-detect format from content
DataForge.parse(String content)

// Explicit format
DataForge.parse(String content, DataFormat.XML)
DataForge.parse(String content, DataFormat.JSON)

// From file (format detected by extension)
DataForge.parseFile("data.xml")
DataForge.parseFile("data.json")

// Create empty document
DataForge.create("rootElementName")

Get Values

// By tag name (deep search — finds anywhere in tree)
doc.getValueByTag("tagName")              // Optional<String> — first match
doc.getAllValuesByTag("tagName")           // List<String> — all matches

// By dot-notation path
doc.getValueByPath("person.address.city") // Optional<String>
doc.getNodeByPath("person.address")       // Optional<DataNode>

// Search
doc.findFirst("tagName")                  // Optional<DataNode>
doc.findAll("tagName")                    // List<DataNode>

Set Values

// By tag name
doc.setValueByTag("tag", "newValue")      // int — updates ALL matches, returns count
doc.setFirstValueByTag("tag", "newValue") // boolean — updates first match only

// By path (creates intermediate nodes if needed)
doc.setValueByPath("a.b.c", "value")

Tree Manipulation

// Add children
doc.addChild("parentTag", "childName", "childValue")
doc.addChild("parentTag", dataNode)
doc.addToRoot("name", "value")
doc.addToRoot(dataNode)

// Remove
doc.removeByTag("tagName")               // int — returns count removed

// Clone
DataNode clone = doc.root().deepClone()

// Node info
node.path()                               // "root.person.address.city"
node.depth()                              // int
node.isLeaf()                             // boolean

Serialization & Conversion

// Serialize
doc.toXml()                               // Pretty-printed with declaration
doc.toJson()                              // Pretty-printed
doc.serialize()                           // Back to original format

// Custom writers
doc.toXml(XmlWriter.compact())
doc.toJson(JsonWriter.compact())
doc.toXml(XmlWriter.builder().declaration(false).indent("    ").build())

// Format conversion
doc.convert()                             // XML->JSON or JSON->XML
doc.convertTo(DataFormat.JSON)

// Write to file
doc.writeTo("output.xml")
doc.writeTo("output.json")

Validation

Define rules in YAML:

rules:
  username:
    required: true
    type: string
    minLength: 3
    maxLength: 20
    pattern: ^[a-zA-Z0-9_]+$
    message: "Username must be 3-20 alphanumeric characters"

  age:
    required: true
    type: integer
    min: 18
    max: 120

  email:
    required: true
    notEmpty: true

  status:
    type: string
    enum:
      - active
      - inactive
      - pending

  address:
    required: true
    type: object
    children:
      city:
        required: true
        type: string
      zip:
        required: true
        pattern: ^[0-9]{5}$

Supported validation rules:

Rule Description Example
required Field must exist true
type Type check: string, integer, number, boolean, object, array integer
min Minimum numeric value 0
max Maximum numeric value 150
minLength Minimum string length 3
maxLength Maximum string length 100
pattern Regex pattern ^[A-Z]+$
enum Allowed values list [a, b, c]
notEmpty Value must not be blank true
message Custom error message "Invalid!"
children Nested validation rules for child nodes (nested mapping)

Apply validation:

// From YAML string
ValidationResult result = doc.validate(yamlString);

// From YAML file
ValidationResult result = doc.validateWithFile("rules.yaml");

// Pre-built engine (reusable)
ValidationEngine engine = ValidationEngine.fromYaml(yamlString);
ValidationResult result = doc.validate(engine);

// Inspect results
result.isValid()                 // boolean
result.errorCount()              // int
result.getErrors()               // List<ValidationError>
result.errorsForPath("username") // errors at specific path
result.report()                  // human-readable report

Project Structure

dataforge/
  src/io/dataforge/
    DataForge.java              # Main facade API
    core/
      DataNode.java             # Unified tree data model
      DataFormat.java           # XML/JSON enum with detection
      DataForgeException.java   # Base exception
      NodeType.java             # Node type enum
    parser/
      XmlParser.java            # Hand-written XML parser
      JsonParser.java           # Hand-written JSON parser
      YamlParser.java           # Hand-written YAML parser
    writer/
      XmlWriter.java            # XML serializer with builder
      JsonWriter.java           # JSON serializer with builder
    validation/
      ValidationEngine.java     # YAML-driven validation engine
      ValidationRule.java       # Rule model
      ValidationResult.java     # Result aggregator
      ValidationError.java      # Error record
  test/io/dataforge/
    DataForgeTest.java          # 117 comprehensive tests
  demo/
    DataForgeDemo.java          # Full feature demo

Building & Running

# Requires Java 25+
export JAVA_HOME=/path/to/jdk-25
export PATH=$JAVA_HOME/bin:$PATH

# Compile library
mkdir -p build
javac -d build src/io/dataforge/core/*.java \
               src/io/dataforge/parser/*.java \
               src/io/dataforge/writer/*.java \
               src/io/dataforge/validation/*.java \
               src/io/dataforge/DataForge.java

# Run tests (117 tests)
javac -cp build -d build test/io/dataforge/DataForgeTest.java
java -cp build io.dataforge.DataForgeTest

# Run demo
javac -cp build -d build demo/DataForgeDemo.java
java -cp build io.dataforge.demo.DataForgeDemo

# Package as JAR
cd build && jar cf ../dataforge.jar io/ && cd ..

Java 25 Features Used

  • RecordsValidationError as an immutable data carrier
  • Sealed types ready — NodeType enum for exhaustive pattern matching
  • Pattern matchingswitch expressions with arrow syntax
  • Switch expressions — Throughout parsers, writers, and facade
  • Text blocks — Multi-line strings in tests and YAML configs
  • SequencedCollectionsSequencedMap for ordered XML attributes
  • Enhanced OptionalifPresentOrElse, fluent chains
  • String.formatted() — Modern string formatting
  • List.of(), toList() — Immutable collection factories

License

MIT

About

Data Forge Library to parse XML and JSON using only JAVA with no external libraries

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages