Developing a XSLT Transformer
Prerequisites
- Understand the desired component for development as described in the DDF Catalog section.
- Review existing implementations in the source code and application documentation.
- Have an IDE and the ability to create OSGi bundles.
- Understand the Use of the Whiteboard Design Pattern section and how to publish services to the OSGi service registry.
XSLT Transformer Framework
The XSLT Transformer Framework allows developers to create light-weight Query Response Transformers and Metacard Transformers using only a bundle header and XSLT files. The XSLT Transformer Framework registers bundles, following the XSLT Transformer Framework bundle pattern, as new transformer services. The service-xslt-transformer
feature is part of the DDF core.
Examples
Examples of XSLT Transformers using the XSLT Transformer Framework include service-atom-transformer
and service-html-transformer
,
found in the services
folder of the source code trunk.
Implement XSLT Transformer
- Create a new Maven Project.
- Configure the POM to create a bundle using the Maven Bundle Plugin.
- Add the transform output MIME type to the bundle headers.
- Add XSLT files.
Bundle POM Configuration
Configure the Maven project to create an OSGi bundle using the maven-bundle-plugin
. Change the DDF-Mime-Type
to match the MIME type of the transformer output.
... <build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> <configuration> <instructions> <DDF-Mime-Type>[[Transform Result MIME Type]]</DDF-Mime-Type> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Import-Package /> <Export-Package /> </instructions> </configuration> </plugin> </plugins> </build> ...
Including XSLT
The XSLT Transformer Framework will scan for XSLT files inside a bundle. The XSLT file must have a .xsl
or .xslt
file in the correct directory location relative to the root of the bundle. The path depends on if the XSLT will act as a Metacard Transformer, Query Response Transformer, or both. The name of the XSLT file will be used as the transformer's shortname.
// Metacard Transformer <bundle root> /OSGI-INF /ddf /xslt-metacard-transformer /<transformer shortname>.[xsl|xslt] // Query Response Transformer <bundle root> /OSGI-INF /ddf /xslt-response-queue-transformer /<transformer shortname>.[xsl|xslt]
The XSLT file has access to Metacard or Query Reponse XML data depending on which folder the XSLT file is located. The Metacard XML format will depend on the metadata schema used by the Catalog Provider.
For Query Response XSLT Transformers, the available XML data for XSLT transform has the following structure:
<results> <metacard> <id>[[Metacard ID]]</id> <score>[[Relevance score]]</score> <distance>[[Distance from query location]]</distance> <site>[[Source of result]]</site> <type qualifier="type">[[Type]]</type> <updated>[[Date last updated]]</updated> <geometry>[[WKT geometry]]</geometry> <document> [[Metacard XML]] </document> </metacard> ... </results>
The XSLT file has access to additional parameters. The Map<String, Serializable> arguments
from the transform
method parameters is merged with the available XSLT parameters.
- Query Response Transformers
grandTotal
- total result count
- Metacard Transformers
id
- Metacard IDsiteName
- Source IDservices
- list of displayable titles and URLs of available Metacard transformers
RSS Example
service-rss-transformer
. Add the following to its POM file.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <packaging>bundle</packaging> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>services</artifactId> <groupId>ddf</groupId> <version>[[DDF release version]]</version> </parent> <groupId>ddf.services</groupId> <artifactId>service-rss-transformer</artifactId> <build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> <configuration> <instructions> <DDF-Mime-Type>application/rss+xml</DDF-Mime-Type> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Import-Package /> <Export-Package /> </instructions> </configuration> </plugin> </plugins> </build> </project>
Line # | Comment |
---|---|
8 | Use the current release version. |
21 | Set the MIME type to the RSS MIME type. |
Add service-rss-transformer/src/main/resources/OSGI-INF/ddf/xslt-response-queue-transformer/rss.xsl
. The transformer will be a Query Response Transformer with the shortname rss
based on the XSL filename and path. Add the following XSL to the new file.
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ddms="http://metadata.dod.mil/mdr/ns/DDMS/2.0/" xmlns:gml="http://www.opengis.net/gml" exclude-result-prefixes="xsl ddms gml"> <xsl:output method="xml" version="1.0" indent="yes" /> <xsl:param name="grandTotal" /> <xsl:param name="url" /> <xsl:template match="/"> <xsl:apply-templates /> </xsl:template> <xsl:template match="results"> <rss version="2.0"> <channel> <title>Query Results</title> <link><xsl:value-of select="$url" disable-output-escaping="yes" /></link> <description>Query Results of <xsl:value-of select="count(//metacard)" /> out of <xsl:value-of select="$grandTotal" /></description> <xsl:for-each select="metacard/document"> <item> <guid> <xsl:value-of select="../id" /> </guid> <title> <xsl:value-of select="Data/title" /> </title> <link> <xsl:value-of select="substring-before($url,'/services')" /><xsl:text>/services/catalog/</xsl:text><xsl:value-of select="../id" /><xsl:text>?transform=html</xsl:text> </link> <description> <xsl:value-of select="//description" /> </description> <author> <xsl:choose> <xsl:when test="Data/creator"> <xsl:value-of select="Resource/creator//name" /> </xsl:when> <xsl:when test="Data/publisher"> <xsl:value-of select="Data/publisher//name" /> </xsl:when> <xsl:when test="Data/unknown"> <xsl:value-of select="Data/unknown//name" /> </xsl:when> </xsl:choose> </author> <xsl:if test=".//@posted" > <pubDate> <xsl:value-of select=".//posted" /> </pubDate> </xsl:if> </item> </xsl:for-each> </channel> </rss> </xsl:template> </xsl:stylesheet>
Line # | Comment |
---|---|
8-9 | Example of using additional parameters and arguments. |
15 | Example of using the Query Response XML data. |
21,27 | Example of using the Metacard XML data. |