A Java object tree implementation based on the Composite Pattern combined with a tolerant XML reader for reading and writing any Extensible Markup Language (XML) structure - no need for an XML Schema Definition XSD.
███████████ █████████ █████ █████
▒▒███▒▒▒▒▒███ ███▒▒▒▒▒███ ▒▒███ ▒▒███
▒███ ▒███ ▒███ ▒███ ▒▒███ ███
▒██████████ ▒███████████ ▒▒█████
▒███▒▒▒▒▒▒ ▒███▒▒▒▒▒███ ███▒███
▒███ ▒███ ▒███ ███ ▒▒███
█████ █████ █████ █████ █████
▒▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒
Each created object can be stored as a node in a tree. There are no special types. Any object can start a fresh tree by being root. A root can store children. Those can be added or set. Any children can be fetched by tag or in case of many with the same name, by listing and filtering. Each object can also store attributes. Those are organized in the same way as child but are used as a list. By any object, the tree can be recursed and generated to any data format. Currently, the generation of XML is implemented only.
./gradlew build jarGet the factory to create new nodes:
IFactory factory = Instances.Factory();Create a new node with a tag name:
IPax root = Instances.Factory().produce("root");Create a new node with a tag and value:
IPax element = Instances.Factory().produce("title", "Effective Java");Create a deep copy of an existing node:
IPax original = Instances.Factory().produce("book");
IPax copy = Instances.Factory().copy(original);All node operations are available through the IPax interface.
IPax root = Instances.Factory().produce("book");
String tag = root.Tag(); // returns "book"IPax root = Instances.Factory().produce("root");
root.Tag("book"); // changes tag to "book"IPax node = Instances.Factory().produce("element");
boolean hasTag = node.hasTag(); // true
IPax noTag = Instances.Factory().produce(null);
boolean empty = noTag.hasTag(); // falseIPax title = Instances.Factory().produce("title", "My Book");
String value = title.Val(); // returns "My Book"IPax element = Instances.Factory().produce("description");
element.Val("A great book");IPax element = Instances.Factory().produce("empty");
boolean hasValue = element.hasVal(); // false
element.Val("content");
hasValue = element.hasVal(); // trueNote: Empty, blank, or newline-only values are rejected and stored as null.
IPax parent = Instances.Factory().produce("parent");
IPax child = Instances.Factory().produce("child");
parent.Child().add(child);
IPax foundParent = child.Parent(); // returns parentIPax parent = Instances.Factory().produce("parent");
IPax child = Instances.Factory().produce("child");
child.Parent(parent);IPax root = Instances.Factory().produce("root");
boolean hasParent = root.hasParent(); // false
IPax child = Instances.Factory().produce("child");
root.Child().add(child);
hasParent = child.hasParent(); // trueIPax root = Instances.Factory().produce("library");
IPax book = Instances.Factory().produce("book");
root.Child().add(book);
IPax chapter = Instances.Factory().produce("chapter");
book.Child().add(chapter);
String path = chapter.Path(); // returns "/library/book/chapter"IChildren children = root.Child();boolean has = root.hasChild();IAttributes attributes = root.Attrib();boolean has = root.hasAttrib();IPax root = Instances.Factory().produce("book");
root.Attrib().add("id", "1");
IPax title = Instances.Factory().produce("title", "Effective Java");
root.Child().add(title);
String xml = root.XML();
/*
<book id="1">
<title>Effective Java</title>
</book>
*/String xml = root.XML_lined(); // <book id="1"><title>Effective Java</title></book>Manage child nodes.
root.Child().add("chapter");root.Child().add("author", "Joshua Bloch");IPax chapter = Instances.Factory().produce("chapter", "Introduction");
root.Child().add(chapter);IPax chapter = root.Child().get("chapter");IPax first = root.Child().get(0);boolean exists = root.Child().has("chapter");List<IPax> allChildren = root.Child().all();List<IPax> chapters = root.Child().all("chapter");int count = root.Child().cnt();root.Child().del("chapter");root.Child().del(chapter);root.Child().del();root.Child().set("title", "New Title");root.Child().set(newChapter);IPax found = root.Child().search("/library/book/chapter");
IPax foundRelative = root.Child().search("./book/chapter");Manage attributes on a node.
root.Attrib().add("id", "123");
root.Attrib().add("type", "novel");IPax attr = Instances.Factory().produce("class", "primary");
root.Attrib().add(attr);IPax id = root.Attrib().get("id");
String value = id.Val(); // "123"boolean hasId = root.Attrib().has("id");List<IPax> attrs = root.Attrib().all();int count = root.Attrib().cnt();root.Attrib().del("id");root.Attrib().del();String attrXml = root.Attrib().XML(); // returns "id=\"123\" type=\"novel\" "Parse XML from various sources.
Reader reader = Reader.Instance;IPax root = Reader.Instance.parse("./config.xml");IPax root = Reader.Instance.parseLocalFile("data.xml");String xml = "<book><title>Java</title></book>";
InputStream is = new ByteArrayInputStream(xml.getBytes());
IPax root = Reader.Instance.stream(is);Write IPax trees to files.
Writer writer = Writer.Instance;IPax book = Instances.Factory().produce("book");
book.Val("Content");
boolean success = Writer.Instance.XML(book); // writes to "book.xml"boolean success = Writer.Instance.XML(book, "mybook.xml");
boolean success2 = Writer.Instance.XML(book, "output"); // adds .xml automatically// Create root
IPax library = Instances.Factory().produce("library");
// Add attributes
library.Attrib().add("name", "City Library");
library.Attrib().add("location", "Downtown");
// Add children
IPax book1 = Instances.Factory().produce("book");
book1.Attrib().add("id", "1");
book1.Child().add("title", "Effective Java");
book1.Child().add("author", "Joshua Bloch");
library.Child().add(book1);
IPax book2 = Instances.Factory().produce("book");
book2.Attrib().add("id", "2");
book2.Child().add("title", "Clean Code");
book2.Child().add("author", "Robert Martin");
library.Child().add(book2);
// Generate XML
String xml = library.XML();
System.out.println(xml);Output:
<library name="City Library" location="Downtown">
<book id="1">
<title>Effective Java</title>
<author>Joshua Bloch</author>
</book>
<book id="2">
<title>Clean Code</title>
<author>Robert Martin</author>
</book>
</library>// Read from file
IPax library = Reader.Instance.parse("library.xml");
// Find specific book using search
IPax book = library.Child().search("/library/book");
// Add new child
IPax review = Instances.Factory().produce("review", "Excellent!");
book.Child().add(review);
// Write back to file
Writer.Instance.XML(library, "library_updated.xml");IPax original = Instances.Factory().produce("book");
original.Attrib().add("id", "1");
original.Child().add("title", "Original");
IPax copy = Instances.Factory().copy(original);
copy.Attrib().add("id", "2");
copy.Child().get("title").Val("Copy");
// Both nodes exist independentlyGradle Wrapper is generated in version 9; try:
./gradlew build jarIf you need to settle another version of the wrapper, get the latest gradle version and install it.
The change to your cloned directory of jPAX and
gradle wrapper
./gradlew buildMIT License - See LICENSE file