Upload
lars-trieloff
View
2.456
Download
2
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
DAX: Where Flowscript meets XSLT
Lars Trieloff, Mindquarry
Lars Trieloff
• Entrepreneur, Blogger, Open Source Coder
• OSS Projects
• Apache Cocoon
• Mindquarry
• Goshaky
• DAX
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
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
DAX Modules and Dependencies
DAX
DAX Modules and Dependencies
DAX
DAX-Java
DAX Modules and Dependencies
DAX
DAX-Java
dom4j
DAX Modules and Dependencies
DAX
DAX-Java
dom4j
DAX-Javascript
DAX Modules and Dependencies
DAX
DAX-Java
dom4j Rhino
DAX-Javascript
DAX Modules and Dependencies
DAX
DAX-Java
dom4j Rhino
DAX-Javascript
DAX-Cocoon
DAX Modules and Dependencies
DAX
DAX-Java
dom4j Rhino Cocoon
DAX-Javascript
DAX-Cocoon
DAX-Java
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); } }}
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); } }}
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); } }}
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
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 />
DAX-Javascript
Why?DAX-Javascript
• XSLT is fine for transforming XML
• but no side-effects possible
• no access to external data model
Input XSLT Output
Model
?
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)
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(); });});
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()|@*"}) });});
• 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
DAX-Cocoon
How to use it DAX-Cocoon
<map:components> <map:transformers> <map:transformer name="dax" src="dax.cocoon.DAXTransformer" /> </map:transformers></map:components>
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>
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()|@*"}) });});
• 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
• 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
How to go on?• Read more
• http://www.asciiarmor.com/2005/03/03/introducing-dax-declarative-api-for-xml/
• https://www.mindquarry.org/wiki/dax/
• http://www.codeconsult.ch/bertrand/archives/000802.html
• Download
• http://releases.mindquarry.org/dax/
• (Maven artifacts available)
Thank you very [email protected]
For more information, see my weblog athttp://weblogs.goshaky.com/weblog/lars