31
DAX: Where Flowscript meets XSLT Lars Trieloff, Mindquarry

Dax Declarative Api For Xml

Embed Size (px)

DESCRIPTION

DAX is a declarative API for processing XML in Java or Javascript that integrates into Cocoon and re-uses important concepts of XPath and XSLT.

Citation preview

Page 1: Dax   Declarative Api For Xml

DAX: Where Flowscript meets XSLT

Lars Trieloff, Mindquarry

Page 2: Dax   Declarative Api For Xml

Lars Trieloff

• Entrepreneur, Blogger, Open Source Coder

• OSS Projects

• Apache Cocoon

• Mindquarry

• Goshaky

• DAX

Page 3: Dax   Declarative Api For Xml

What is DAX

• DAX means Declarative API for XML

• A way to process XML

• By expressing what parts of a document you want to process

• Based on Java, Javascript and Cocoon

Page 4: Dax   Declarative Api For Xml

DAX History

• Feb 2005: Kim Wolk writes XMLTO, a .NET library that transforms XML into objects

• March 2005: Ryan Cox ports it to Java 5, using Annotations and dom4j‘s Transformer API

• 2006 to 2007: DAX is used in production at Mindquarry, adopted to Cocoon

Page 5: Dax   Declarative Api For Xml

DAX Modules and Dependencies

DAX

Page 6: Dax   Declarative Api For Xml

DAX Modules and Dependencies

DAX

DAX-Java

Page 7: Dax   Declarative Api For Xml

DAX Modules and Dependencies

DAX

DAX-Java

dom4j

Page 8: Dax   Declarative Api For Xml

DAX Modules and Dependencies

DAX

DAX-Java

dom4j

DAX-Javascript

Page 9: Dax   Declarative Api For Xml

DAX Modules and Dependencies

DAX

DAX-Java

dom4j Rhino

DAX-Javascript

Page 10: Dax   Declarative Api For Xml

DAX Modules and Dependencies

DAX

DAX-Java

dom4j Rhino

DAX-Javascript

DAX-Cocoon

Page 11: Dax   Declarative Api For Xml

DAX Modules and Dependencies

DAX

DAX-Java

dom4j Rhino Cocoon

DAX-Javascript

DAX-Cocoon

Page 12: Dax   Declarative Api For Xml

DAX-Java

Page 13: Dax   Declarative Api For Xml

How to use itDAX-Java

public class ElementCounter extends Transformer { Map elements = new Hashmap<String, Integer>(); public void processElement(Node context) { String name = context.getName(); if (elements.hasKey(name)) { elements.put(name, elements.get(name) + 1); } else { elements.put(name, 1); } }}

Page 14: Dax   Declarative Api For Xml

How to use itDAX-Java

public class ElementCounter extends Transformer { Map elements = new Hashmap<String, Integer>(); @Path("*") //select all elements public void processElement(Node context) { String name = context.getName(); if (elements.hasKey(name)) { elements.put(name, elements.get(name) + 1); } else { elements.put(name, 1); } }}

Page 15: Dax   Declarative Api For Xml

How to use itDAX-Java

public class SourceCounter extends Transformer { Map sources = new Hashmap<String, Integer>(); @Path("img[@src]") //select all elements public void processElement(Node context) { String name = this.valueOf("@src"); if (elements.hasKey(name)) { elements.put(name, elements.get(name) + 1); } else { elements.put(name, 1); } }}

Page 16: Dax   Declarative Api For Xml

How it worksDAX-Java

• Simple parsing algorithm:

• traverse the DOM of the XML document

• for each node, find an annotated method

• with matching XPath

• execute this method

• Just like XSLT's templates

Page 17: Dax   Declarative Api For Xml

vs XSLTDAX-Java

DAX-Java XSLT

Templates @Path("/foo/bar")public void bar(Node context) <xsl:template match="/foo/bar">

Value-Of valueOf("@bar") <xsl:value-of select="@bar" />

Apply-Templates

applyTemplates() <xsl:apply-templates />

Page 18: Dax   Declarative Api For Xml

DAX-Javascript

Page 19: Dax   Declarative Api For Xml

Why?DAX-Javascript

• XSLT is fine for transforming XML

• but no side-effects possible

• no access to external data model

Input XSLT Output

Model

?

Page 20: Dax   Declarative Api For Xml

Background DAX-Javascript

• Map most important XSLT concepts to Javascript concepts

XSLT Javascript

<xsl:stylesheet> Stylesheet object

<xsl:template> template function of the Stylesheet object

<xsl:apply-templates/> applyTemplate function of the Stylesheet object

<xsl:copy/> copy function of the Stylesheet object (with inlined body function)

Page 21: Dax   Declarative Api For Xml

How to use it DAX-Javascript

<xsl:template match="foo"> <bar> <xsl:comment>example code uses foo</xsl:comment> <xsl:apply-templates /> </bar></xsl:template/>

Stylesheet.template({match:"foo"}, function(node) { this.element("bar", function(node) { this.comment("example code uses foo"); this.applyTemplates(); });});

Page 22: Dax   Declarative Api For Xml

How to use it DAX-Javascript

<xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*" /> </xsl:copy></xsl:template/>

Stylesheet.template({match:"node()|@*"}, function(node) { this.copy(function(node) { this.applyTemplates({select:"node()|@*"}) });});

Page 23: Dax   Declarative Api For Xml

• Uses Rhino Javascript Engine

• full access to Java object model

• allows side-effects when transforming XML

• Parses the incoming XML stream

• Finds and fires matching functions

How it works DAX-Javascript

Page 24: Dax   Declarative Api For Xml

DAX-Cocoon

Page 25: Dax   Declarative Api For Xml

How to use it DAX-Cocoon

<map:components> <map:transformers> <map:transformer name="dax" src="dax.cocoon.DAXTransformer" /> </map:transformers></map:components>

Page 26: Dax   Declarative Api For Xml

How to use it DAX-Cocoon

<map:match pattern="/resource/*"> <map:select type="request-method"> <map:generate type="stream" /> <map:when test="PUT"> <map:transform type="dax" src="dax/res.js"> <map:parameter name="res" value="{1}" /> </map:transform> </map:when> </map:select></map:match>

Page 27: Dax   Declarative Api For Xml

How to use it DAX-Cocoon

var resourcemanager = cocoon.getComponent("resourcemanager");

Stylesheet.template({match:"del"}, function(node) { var that = this; this.copy(function(node) { if (that.valueOf(".")==cocoon.parameters.res) { resourcemanager.delete(that.valueOf("@node")) } this.applyTemplates({select:"node()|@*"}) });});

Page 28: Dax   Declarative Api For Xml

• Implemented as a Cocoon Transformer

• Pull in "cocoon" object as Flowscript does

• Usage Scenario: REST Application

• validate using DAX (e.g. by checking database)

• transform using DAX (e.g by triggering actions)

• save using DAX (e.g. by changing model)

How it works DAX-Cocoon

Page 29: Dax   Declarative Api For Xml

• Caching

• We do not know if a transformation has non-cacheable side-effects

• Mixing DAX and XSLT

• perhaps E4X is a way to conveniently embed XSLT

• Not all XSLT concepts implemented (sorting)

Open QuestionsDAX-Cocoon

Page 31: Dax   Declarative Api For Xml

Thank you very [email protected]

For more information, see my weblog athttp://weblogs.goshaky.com/weblog/lars