dax declarative api for xml

Post on 09-May-2015

2.440 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

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.

TRANSCRIPT

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

Thank you very muchlars@trieloff.net

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

top related