Dax Declarative Api For Xml - Presentation 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-
DAX-Java
Javascript
dom4j
DAX Modules and
Dependencies
DAX
DAX-
DAX-Java
Javascript
dom4j Rhino
DAX-Java How to use it
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);
}
}
}
DAX-Java How to use it
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);
}
}
}
DAX-Java How to use it
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);
}
}
}
DAX-Java How it works
• 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
DAX-Javascript Why?
• XSLT is fine for transforming XML
• but no side-effects possible
• no access to external data model
Input XSLT Output
?
Model
DAX-Javascript Background
• Map most important XSLT concepts to
Javascript concepts
XSLT Javascript
<xsl:stylesheet> Stylesheet object
template function of the Stylesheet
<xsl:template>
object
applyTemplate function of the
<xsl:apply-templates/>
Stylesheet object
copy function of the Stylesheet object
<xsl:copy/>
(with inlined body function)
DAX-Javascript How to use it
<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();
});
});
DAX-Javascript How to use it
<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()|@*\"})
});
});
DAX-Javascript How it works
• 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
DAX-Cocoon
DAX-Cocoon How to use it
<map:components>
<map:transformers>
<map:transformer name=\"dax\"
src=\"dax.cocoon.DAXTransformer\" />
</map:transformers>
</map:components>
DAX-Cocoon How to use it
<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>
DAX-Cocoon How to use it
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()|@*\"})
});
});
DAX-Cocoon How it works
• 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)
DAX-Cocoon Open Questions
• 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)
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 much
lars@trieloff.net
For more information, see my weblog at
http://weblogs.goshaky.com/weblog/lars
0 comments
Post a comment