Agreed. This is very cool!

Roger, just curious, do you know if Saxon allows returning a native Java
XML representation rather than having to convert the JDOM to a  string
and then requiring parse-xml? Perhaps we would need a Saxon specific
InfosetOutputter?

- Steve


On 6/2/20 12:22 PM, Beckerle, Mike wrote:
> Nice!
> 
> Would you mind if we include this example in the OpenDFDL web site?
> 
> I think people would like to see how this is done for reference, learning, 
> etc.
> 
> ...mikeb
> --------------------------------------------------------------------------------
> *From:* Roger L Costello <coste...@mitre.org>
> *Sent:* Tuesday, June 2, 2020 12:10 PM
> *To:* users@daffodil.apache.org <users@daffodil.apache.org>
> *Subject:* Here's how XSLT programs can use DFDL/Daffodil
> 
> Hi Folks,
> 
> Below is an XSLT program that processes XML-formatted CSV. The XSLT program 
> calls an external Java program, passing it the name of a DFDL file 
> (csv.dfdl.xsd) and the name of a CSV file (csv.txt). The Java program calls 
> Daffodil which produces XML-formatted CSV. The Java program returns the XML 
> as a 
> string. The XSLT program uses the parse-xml() function to convert the string 
> to 
> XML.
> 
> <xsl:stylesheetxmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> xmlns:xs="http://www.w3.org/2001/XMLSchema";
> xmlns:dfdl="java:runDaffodil"
> version="3.0">
> 
> <xsl:variablename="dfdl"select="'csv.dfdl.xsd'"/>
> <xsl:variablename="input"select="'csv.txt'"/>
> 
> <xsl:templatematch="/">
> <!-- Convert the CSV text file to XML using DFDL -->
> <xsl:variablename="csv-string"select="/dfdl:dfdlParse/(*$dfdl*,*$input*)"as="xs:string"/>
> <xsl:variablename="csv-xml"select="/parse-xml/(*$csv-string*)"as="document-node()"/>
> <!-- Process the XML-formatted CSV here -->
> <xsl:variablename="numRecords"select="/count/(*$csv-xml*//*record*)"as="xs:integer"/>
> <!-- Output the number of records in the CSV file -->
> <xsl:sequenceselect="*$numRecords*"/>
> <!-- Output the model (field 3) and year (field 1) of each Chevy auto -->
> <xsl:for-eachselect="*$csv-xml*//*record*[*field*[2] eq'Chevy']">
> <xsl:sequenceselect="(*field*[3]//data/(),' ',*field*[1]//data/())"/>
> </xsl:for-each>
> </xsl:template>
> </xsl:stylesheet>
> 
> The XSLT program uses XSLT version 3.0. You can use any version except 1.0 
> (the 
> parse-xml() function is not present in XSLT 1.0). I used Saxon as the XSLT 
> processor.
> 
> The Java program calls Daffodil which parses the CSV file using the DFDL 
> schema. 
> Here is the Java program:
> 
> *import*java.io.IOException;
> *import*java.net.URISyntaxException;
> *import*java.net.URL;
> 
> *import*org.jdom2.Document;
> *import*org.jdom2.output.XMLOutputter;
> 
> *import*org.apache.daffodil.japi.Compiler;
> *import*org.apache.daffodil.japi.Daffodil;
> *import*org.apache.daffodil.japi.DataProcessor;
> *import*org.apache.daffodil.japi.Diagnostic;
> *import*org.apache.daffodil.japi.ParseResult;
> *import*org.apache.daffodil.japi.ProcessorFactory;
> *import*org.apache.daffodil.japi.infoset.JDOMInfosetOutputter;
> *import*org.apache.daffodil.japi.io.InputSourceDataInputStream;
> 
> *public**class*runDaffodil {
> 
> *public**static*String dfdlParse(String dfdl,String 
> input)*throws*IOException,URISyntaxException {
> 
> URL dfdlURL =runDaffodil.*class*.getResource(dfdl);
> URL inputURL =runDaffodil.*class*.getResource(input);
> 
> //
> // First, compile the DFDL Schema
> //
> Compiler c =Daffodil.compiler();
> ProcessorFactory pf =c.compileSource(dfdlURL.toURI());
> DataProcessor dp =pf.onPath("/");
> 
> //
> // Parse - parse data to XML
> //
> java.io.InputStream is =inputURL.openStream();
> InputSourceDataInputStream dis =*new*InputSourceDataInputStream(is);
> 
> //
> // Setup JDOM outputter
> //
> JDOMInfosetOutputter outputter =*new*JDOMInfosetOutputter();
> 
> //
> // Do the parse
> //
> ParseResult res =dp.parse(dis,outputter);
> 
> //
> // Return the XML as a string
> //
> Document doc =outputter.getResult();
> *return**new*XMLOutputter().outputString(doc);
> }
> }
> 

Reply via email to