shows how to bind Java interfaces to XML documents that use namespaces.
Namespaces
Say you have a given XML file with namespaces, book-ns.xml:
<book title="Treasure Island" xmlns="http://mybook"> <reference url="http://en.wikipedia.org/wiki/Treasure_Island" lang="en"/> <reference url="http://fr.wikipedia.org/wiki/L'Île_au_trésor" lang="fr"/> <publishedIn>1883</publishedIn> <author xmlns:people="a/b/c/"> <people:name>Robert Louis Stevenson</people:name> <people:name>R. L. Stevenson</people:name> </author> </book>
Here is an annotated interface that avc-binding-dom would be able to bind to such an XML document:
package aaa.bbb.ccc; import net.avcompris.binding.annotation.Namespaces; import net.avcompris.binding.annotation.XPath; @Namespaces({"xmlns:m=http://mybook", "xmlns:people=a/b/c/"}) @XPath("/m:book") public interface Book { @XPath("@title") String getTitle(); @XPath("m:publishedIn") int getPublishYear(); @XPath("m:author/people:name") String[] getAuthorNames(); @XPath("m:reference") MyBookReference[] getReferences(); interface MyBookReference { @XPath("@url") String getUrl(); @XPath("@lang") String getLang(); } }
More information about the @Namespaces annotation may be found in the avc-binding-common project's API Documentation.
Binding would take place the following way:
... import java.io.File; import javax.xml.parsers.DocumentBuilderFactory; import net.avcompris.binding.dom.DomBinder; import net.avcompris.binding.dom.impl.DefaultDomBinder; import org.w3c.dom.Document; ... final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilderFactory.setNamespaceAware(true); final Document document = documentBuilderFactory .newDocumentBuilder().parse(new File("book-ns.xml")); final DomBinder binder = new DefaultDomBinder(); final Book book = binder.bind(document, Book.class);
(This sample code is in the project's test sources: NamespacesExamplesTest.)
The @Namespaces annotation allows some other syntax:
@Namespaces({"xmlns:m=http://mybook", "xmlns:people=a/b/c/"}) @Namespaces({"m", "http://mybook", "people", "a/b/c/"})
Of course you can mix the two:
@Namespaces({"xmlns:m=http://mybook", "people", "a/b/c/"}) @Namespaces({"m", "http://mybook", "xmlns:people=a/b/c/"})
Note that neither the @Namespaces nor the @XPath annotation handle namespaces with empty prefixes. You must always explicitely declare a namespace prefix. That is why in our example we use "xmlns:m=http://mybook"
("m"
is arbitrary), and not "xmlns=http://mybook"
.
BindConfiguration.setNamespaces()
Alternatively to the @Namespaces annotation, you can use a BindConfiguration object that will hold namespace declarations. This is convenient when your clazz
interface was not annotated at first.
Use of a BindConfiguration parameter overrides any @Namespaces annotation.
Syntax is the same as with the @Namespaces annotation.