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); > } > } >