Fork me on GitHub

API Reference

Short API reference examples

Projection Interfaces

You define your projection interfaces with getter, setter or deleter methods. The interface may be annotated with the @XBDocURL annotation.

public interface Projection {
    // Define your projection methods in a public interface.
};
 
@XBDocURL("http://...")
public interface ProjectionWithSourceDeclaration {
    // Define your projection methods in a public interface.
    // You may add a document url to specify where to get the document for this projection.
}

XBProjector

Use the XBProjetor class to create, read or write projections.

Create a XBProjector instance

A XMLBeam projector is created with it's default constructor. Alternatively you may pass a XMLFactoriesConfiguration to inject other DocumentBuilders, Transformers or XPath implementations.

XBProjector projector = new XBProjector();

Create a projection from scratch

You may start with an empty document and create the content by writing projection methods. Projections can be bidirectional.

Projection projection = projector.projectEmptyDocument(Projection.class);
 
Projection subProjection = projector.projectEmptyElement(name, Projection.class);

Parse some XML String

Projection projection = projector.projectXMLString("<xml/>", Projection.class);

Convert a projection to a String

// Let the projector convert your projection
String xml = projector.asString(projection);
 
// Or, configure the projector this way before you create a projection
XBProjector projector  = new XBProjector(Flags.TO_STRING_RENDERS_XML);
//... and later call:
projection.toString();

Create a projection for a DOM Document or Element

Projection projection =  projector.projectDOMNode(node, Projection.class);

Read or write a projection to a file

Read XML documents directly into projections or write XML files with one line of code.

Projection projection = projector.io().file(file).read(Projection.class);
 
projector.io().file(file).write(projection);
 
projector.io().file(file).setAppend(true).write(projection);

Read or write a projection with a document origin annotation "@XBDocURL"

You may delegate the specification of the document origin to the projection interface.

Projection projection = projector.io().fromURLAnnotation(Projection.class, params);
 
projector.io().toURLAnnotationViaPOST(projectionInterface, projection, params);

Read or write a projection from or to a given URL

Writing is supported for the protocols file, HTTP and HTTPS. HTTP writing means to post the document to the given URL. Reading supports the additional protocol "resource" to get documents from Java resources. It will use the class loader of the projection interfaces.

Projection projection = projector.io().url(url).read(Projection.class);
 
projector.io().url(url).write(projection);

Adding HTPP headers for get/post requests

Projection projection = projector.io().url(httpurl).addRequestProperty("key", "value").read(Projection.class);
 
Projection projection2 = projector.io().url(httpurl).addRequestProperties(props).read(Projection.class);

You may want to obtain properties for HTTP Basic authentication

Map<String, String> credentials = IOHelper.createBasicAuthenticationProperty("user","pwd");
 
projector.io().url(httpurl).addRequestProperties(credentials).write(projection);

Read or write a projection via Input/Outputstream

Projection projection = projector.io().stream(is).read(Projection.class);
 
Projection projectionWithSystemID = projector.io().stream(is).setSystemID(systemID).read(Projection.class);
 
projector.io().stream(os).write(projection);

Let a projection return a custom type that can be created with a String

To let a projection method return a custom type like this...

public interface MyProjection {
    @XBRead("some/path/to/data")
    MyCustomType getData();
}

... you have to define a String-constructor

public class MyCustomType {
    public MyCustomType(final String data) {
        //...
    }
}

... or define a static factory method named "valueOf", "of", "parse" or "getInstance"

public static MyCustomType valueOf(final String data) {
    return somehowCreateInstanceFor(data);
}
 
public static MyCustomType of(final String data) {
    return somehowCreateInstanceFor(data);
}
 
public static MyCustomType parse(final String data) {
    return somehowCreateInstanceFor(data);
}
 
public static MyCustomType getInstance(final String data) {
    return somehowCreateInstanceFor(data);
}

Dynamic Projections

Dynamic Projections may change the XPath during runtime using parameters of the projection method. There are two ways to use method parameters in XPath expressions:

  • XPath variables: Parameters are bound to XPath variables. The first parameter can be referred by '$PARAM0' or alternatively '$ARG0'. The second parameter by '$PARAM1' or '$ARG1'. Variable names are case insensitive, thus '$Param2' and '$param2' refer both to the third parameter of the projection method. These variables may be decorated by format specifications.
  • Preprocessor: If you need to change more than just values (e.g. the structure of the XPath), you can do this by using the build in preprocessor. The place holders are '{PARAM0}', '{ARG0}' or just '{0}' for the first parameter, '{PARAM1}', '{ARG1}', '{1}' for the second and so on... Like the variables, these tokens are case insensitive. Preprocessor place holders are slower on multiple method invocations, because the XPath expression needs to be compiled every time.

Use parameter names in dynamic projections

You have to use Java 8 and set the javac option "-parameters" for your projection interfaces. Then you can do something like this:

@XBRead("/{parentNode}/{subnode}[@id='{id}']")
String readSomeValue(String parentNode,String subnode,int id);

instead of the pre Java 8 solution:

@XBRead("/{0}/{1}[@id='{2}']")
String readSomeValue(String parentNode,String subnode,int id);

Of course, this works with XPath variables, too.

Annotations

@XBDocURL

This annotation may be used on a projection interface do declare a document origin. When the document is fetched from this URL, this value becomes the system id. As any other annotation string values the URL may contain preprocessor place holders ("{n}", where n=0,1,2... is a parameter index).

When attached to a getter method in a projection interface, this is called an external projection. The getters XPath expression will be evaluated on the document fetched from this URL.

@XBRead

This annotation is used to mark a method as getter. A XPath expression is required as value and the method must have one of the following return types:

  • a primitive value.
  • a String
  • a (sub) projection interface
  • a class with a String constructor
  • a class with a static factory method called 'valueOf(String)', 'of(String)', 'parse(String)', 'getInstance(String)'
  • a DOM-Node (if you need access to the DOM behind the projection).

or a list, array, Stream or Optional of any of these types.

@XBWrite

Marking a method with @XBWrite declares it as a setter. The annotation takes a XPath expression as parameter. Notice that only a subset of the XPath syntax is valid for setters. The expression result must be a Node or NodeSet. (Otherwise there would be no place to store the value, right?)

@XBUpdate

This annotation declares a projection method to update single values on one or more nodes (elements or attributes). In contrast to @XBWrite, here the XPath syntax is not limited.

@XBDelete

The easiest way to remove something from a document is to declare a deleter method. Again this annotation takes a XPath expression as parameter. Again only XPath expressions selecting Nodes or NodeSets are valid here.

@XBAuto

The return type must be a List, Map or the special type XBAutoValue. Changes to the content of the returned instances are directly applied to the XML structure. This is a very convenient way of adding or removing elements. If the return type of the projection method is List or Map, the XPath expression must select a NodeSet.

@XBOverride

It's not possible for Java 8 default methods to override a method inherited from Object. This is bad if you want to have your own hashCode or toString method implemented as a default method. With this annotation you can declare a default method with a different name (e.g. "toString_") and declare it to be used when Object.toString() is called. (@XBOverride("toString"))

Annotation on method parameters

@XBValue

A setter must have at least one parameter. If you choose to declare more than one parameter (because you use them as MessageFormat parameters) then you should mark the parameter to be set in the document with this annotation. If you don't, the first parameter will be the "setting parameter".