JAVA: Build XML document using XPath expressions

10,724

Solution 1

I looked for something similar a few years ago - a sort of writeable XPath. In the end, having not found anything, I hacked up something which essentially built up the XML document by adding new nodes to parent expressions:

parent="/" element="root"
parent="/root" element="entity"
parent="/root/entity" attribute="att" value="fooattrib"
parent="/root" element="array"
parent="/root" element="ele" text="barelement"

(This was itself to be governed by an XML configuration file, hence the appearance of above.)

It would be tempting to try an automate some of this to just take the last path element, and make something of it, but I always felt that there were XPath expressions I could write which such a dumbheaded approach would get wrong.

Another approach I considered, though did not implement (the above was "good enough"), was to use the excellent Jaxen to generate elements that did not exist, on the fly if it didn't already exist.

From the Jaxen FAQ:

The only thing required is an implementation of the interface org.jaxen.Navigator. Not all of the interface is required, and a default implementation, in the form of org.jaxen.DefaultNavigator is also provided.

The DOMWriterNavigator would wrap and existing DOMNavigator, and then use the makeElement method if the element didn't exist. However, even with this approach, you'd probably have to do some pre/post processing of the XPath query for things like attributes and text() functions.

Solution 2

The best I was able to come up with is to use a JAXB implementation, which will marshall/unmarshal objects to xml and then I used Dozer (http://dozer.sourceforge.net/documentation/mapbackedproperty.html) to map the xpaths which were keys in a map to the JAXB object method setters.

<mapping type="one-way" map-id="TC1">
<class-a>java.util.Map</class-a>
<class-b>org.example.Foo</class-b>
<field>
  <a key="root/entity/@att">this</a>
  <b>Foo.entity.att</b>
  <a-hint>java.lang.String</a-hint>
</field>

It's more of a two step solution, but really worked for me.

Solution 3

I also wanted same kind of requirement where nature is so dynamic and dont want to use XSLT or any object mapping frameworks, so i've implemented this code in java and written blog on it please visit,

http://ganesh-kandisa.blogspot.com/2013/08/dynamic-xml-transformation-in-java.html

or fork code at git repository,

https://github.com/TheGanesh/DynamicXMLTransformer

Share:
10,724
Admin
Author by

Admin

Updated on June 29, 2022

Comments

  • Admin
    Admin about 2 years

    I know this isn't really what XPath is for but if I have a HashMap of XPath expressions to values how would I go about building an XML document. I've found dom-4j's DocumentHelper.makeElement(branch, xpath) except it is incapable of creating attributes or indexing. Surely a library exists that can do this?

    Map xMap = new HashMap();
    
    xMap.put("root/entity/@att", "fooattrib");
    xMap.put("root/array[0]/ele/@att", "barattrib");
    xMap.put("root/array[0]/ele", "barelement");
    xMap.put("root/array[1]/ele", "zoobelement");
    

    would result in:

    <root>
    <entity att="fooattrib"/>
    <array><ele att="barattrib">barelement</ele></array>
    <array><ele>zoobelement</ele></array>
    </root>