Search code examples
solrsolrjsolr4

Custom format XML from Solr


I have a product data in Solr. Solr already provides them into XML via query.

However, I need the data into different XML format (just name of xml nodes are different) for supplying them as a feeds to some other application.

Any idea, how can I do this quickly from Solr?


Solution

  • I finally managed to do this using one of existing response writer. This does not require writing a new response writer. Here is how I did it.

    I have used XSLTResponseWriter to generate custom format xml. You can find more details here: http://wiki.apache.org/solr/XsltResponseWriter

    You can find more information on how to use response writer here: https://wiki.apache.org/solr/QueryResponseWriter

    Okay, now before you use it, it needs to be configured.

    Step 1: Define QueryResponseWriter for XSLT in your solrconfig.xml

    Add following code into your solrconfig.xml after ending your Query component.

    <!--
      Changes to XSLT transforms are taken into account
      every xsltCacheLifetimeSeconds at most.
    -->
    <queryResponseWriter name="xslt" class="org.apache.solr.response.XSLTResponseWriter">
      <int name="xsltCacheLifetimeSeconds">5</int>
    </queryResponseWriter>
    

    You can find its documentation at http://wiki.apache.org/solr/XsltResponseWriter

    Step 2. Use proper xslt format or customize your own

    You can either use existing xslt formats provided in default Solr download or use it to modify it the way you want it to work. There are 5 example formats provided already. Suppose you use example.xsl which generates a document in html with all fields, then you need to query it like this.

    I customized it to use custom.xsl file format to implement my own format. I'll come to it later.

    Step 3. Query your Solr using XSLT

    http://localhost:8983/solr/mysolrcore/select?q=*:*&wt=xslt&tr=default.xsl&&rows=10
    

    This will query solr and will present data in a format defined in default.xsl. Note the wt and tr parameter. You can pass how many records you want in result in rows.

    Custom XML format using XSLT

    Here's how I formatted my custom xml format using xslt. Hope this might be helpful to someone.

    I have used example_rss.xsl as a base to start with and modified it as following.

    <?xml version='1.0' encoding='UTF-8'?>
    
    <!-- 
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     -->
    
    <!-- 
      Sample transform of Solr query results to custom XML format
     -->
    
    <xsl:stylesheet version='1.0'
        xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
    
      <xsl:output
           method="xml"
           encoding="utf-8"
           media-type="application/xml"
      />
      <xsl:template match='/'>
        <xml version="1.0">
             <xsl:apply-templates select="response/result/doc"/>
        </xml>
      </xsl:template>
    
      <!-- search results xslt -->
      <xsl:template match="doc">
        <xsl:variable name="id" select="str[@name='Id']"/>
        <xsl:variable name="timestamp" select="date[@name='timestamp']"/>
        <item>
          <id><xsl:value-of select="int[@name='Id']"/></id>
          <title><xsl:value-of select="str[@name='Name']"/></title>
          <link>
            http://localhost:8983/solr/mysolrcore/<xsl:value-of select="string[@name='url']"/>p-<xsl:value-of select="int[@name='Id']"/>
          </link>
          <image>
            <xsl:value-of select="str[@name='ImageURL']"/>
          </image>
          <category><xsl:value-of select="arr[@name='Category']"/></category>
          <availability><xsl:value-of select="bool[@name='StockAvailability']"/></availability>
          <description>
            <xsl:value-of select="str[@name='ShortDescription']"/>
          </description>    
        </item>
      </xsl:template>
    </xsl:stylesheet>
    

    This generates a valid xml document without the need of writing your own custom response writer.