Convert XML to HTML with XSLT in Clojure

Convert XML to HTML with XSLT, using javax.xml package.

 
(defn xslt-transform [xml xslt]
  (let [
         factory (javax.xml.parsers.DocumentBuilderFactory/newInstance)
         builder (.newDocumentBuilder factory)
         document (.parse builder (org.xml.sax.InputSource. (java.io.StringReader. xml)))
         tfactory (javax.xml.transform.TransformerFactory/newInstance)
         xslt-source (javax.xml.transform.stream.StreamSource.  (java.io.StringReader. xslt))
         transformer (.newTransformer tfactory xslt-source)
         source (javax.xml.transform.dom.DOMSource. document)
         writer (java.io.StringWriter.)
         result (javax.xml.transform.stream.StreamResult. writer ) ; System/out
 
       ]
 
    (.setOutputProperty transformer javax.xml.transform.OutputKeys/OMIT_XML_DECLARATION "yes")
    (.transform transformer source result)
    (.toString writer)
  )
)
 

The source XML document

 
<contents>
  <part title="Lucene Basics(or Fundamentals)">
    <chapter title="Lucene Searching">
      <section type="internal" title="Lucene Scoring">
        <leaf title="How Lucene scoring works" seotitle="how-lucene-scoring-works">
        </leaf>
      </section>    
      <section type="terminal" title="" seotitle="">
        <leaf title="hello world" seotitle="how-lucene-scoring-works">
        </leaf>
      </section>
    </chapter>
  </part>
 
  <part title="Lucene Index">
    <chapter title="Lucene Searching">
      <section type="internal" title="Lucene Scoring">
        <leaf title="How Lucene indexing works" seotitle="how-lucene-indexing-works">
        </leaf>
        <leaf title="Lucene Index tutorial" seotitle="lucene-index-tutorial">
        </leaf>
      </section>    
      <section type="terminal" title="" seotitle="">
      </section>
    </chapter>
  </part>  
</contents>
 

The XSLT that defines the transformation template.

 
 <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:template match="/">
         <div class="toc-contents">
             <ul>
                 <xsl:apply-templates/>
             </ul>
         </div>
     </xsl:template>
     <xsl:template match="part">
         <li>
          <div class="toc-part">
              <h1><xsl:value-of select="@title"/></h1>
              <ul>
                  <xsl:apply-templates select="chapter"/>
              </ul>
          </div>
         </li>
     </xsl:template>
     <xsl:template match="chapter">
         <li>
          <div class="toc-chapter">
              <h2><xsl:value-of select="@title"/></h2>
              <ul>
                  <xsl:apply-templates select=".//leaf"/>
              </ul>
          </div>             
         </li>
     </xsl:template>
     <xsl:template match="leaf">
 
         <li>
             <a>
                 <xsl:attribute name="href">http://makble.com/<xsl:value-of select="@seotitle"/>
                </xsl:attribute>
              <xsl:value-of select="@title"/></a>
         </li>
     </xsl:template>
 </xsl:stylesheet>
 

The output document

 
<div class="toc-contents"><ul>
 
  <li><div class="toc-part"><h1>Lucene Basics(or Fundamentals)</h1><ul><li><div class="toc-chapter"><h2>Lucene Searching</h2><ul><li><a href="http://makble.com/how-lucene-scoring-works">How Lucene scoring works</a></li><li><a href="http://makble.com/how-lucene-scoring-works">hello world</a></li></ul></div></li></ul></div></li>
 
 
 
  <li><div class="toc-part"><h1>Lucene Index</h1><ul><li><div class="toc-chapter"><h2>Lucene Searching</h2><ul><li><a href="http://makble.com/how-lucene-indexing-works">How Lucene indexing works</a></li><li><a href="http://makble.com/lucene-index-tutorial">Lucene Index tutorial</a></li></ul></div></li></ul></div></li>  
 
</ul></div>