Steps for XML publication of content

Release 1.3 - ...

This is an example of publication of content in XML format. The example makes use of an added XML channel, an XML render template per contenttype, and some auxiliary translations.

Purpose

The purpose of the solution is to let the CMS publish content in XML format, for use by external applications. External applications visit the site and retrieve the XML content for further processing. Such an application is in the lead; from the viewpoint of the external application it is a pull approach as opposed to a push approach. Probably the external application does searching or navigating on the site, followed by retrieval of the XML content.

Technical setup

The Smartsite iXperion publication engine publishes pages with XML content. Other approaches include the export of content using the Smartsite XML export format, and include obtaining content through the RAW channel. These solutions are built around the CMS engine. The example presented now makes use of the publication engine, allowing for multithreaded, fast, non-blocking retrieval of XML formatted pages.

XML channel

The example makes use of an added XML channel. The channel is not present in the standard initial empty site. You may already have added the channel to your CMS, for other purposes.

Using an XML channel allows for the standard CMS mechanism to combine a publication channel with the contenttype of an item, resulting in the render template to apply in order to publish the content item.

Add an item of the contenttype Channel. For example name the channel XML Channel. Some key properties of this new item are:

  • Code: XML.
  • Description: Channel for XML rendering of content items.
  • Browsable.
  • Default document: xml.net. Your site may already be configured for use of documents with the extension .net. By using xml.net no new extension is introduced, and for example no additional IIS configuration is required and no addiotional configuration of the web.config is required.
  • Id parameter: id.
  • Browse start page: at wish, for example 1 as for the RAW channel.
  • Use friendly names.
  • Locale: not relevant; set as for the RAW channel.
  • Force authentication: at wish.
  • Do not use CMS rendering.
  • Friendly name: XML.
  • Permanent link, and allow for manual updates only.
  • Channel contenttypes: at wish, for example contenttypes News and Project.
  • Channel subtrees: do not filter by subtree.

Render templates

Add one render template per contenttype to be XML-published. For example name the render template for the news contenttype News XML.

  • Description: To render a news item as an XML document.
  • Edit CSS: not required.
  • Use for: select the contenttypes that will use this render template, at least the contenttype News as indicated by News on XML Channel.
  • Do not use Smartsite 5 rendering.
  • Render template content:

Smartsite SXML CopyCode image Copy Code
<se:xhtmlpage doctype="none" encoding="utf-8" xmlns:se="http://smartsite.nl/namespaces/sxml/1.0">
<page>
 <nr type="xsd:int">{itemdata.number()}</nr>
 <title type="xsd:string">{html.cdata(itemdata.name())}</title>
 <contenttype type="xsd:string">{itemdata.contenttypecode()}</contenttype>
 <text type="xsd:string">{html.cdata(itemdata.rawfield(body))}</text>
 <summary type="xsd:string">{html.cdata(itemdata.rawfield(Summary))}</summary>
 <adddate type="xsd:dateTime">{itemdata.rawfield(adddate)}</adddate>
 <code type="xsd:string">{itemdata.code()}</code>
 <language thesaurus="LANGUAGES">
  {xmlthesaurusterms(itemdata.number(), LANGUAGES, Language)}
 </languages>
 <related_news contentrelation="RELATEDNEWS">
  {xmlcontentrelations(itemdata.number(), RELATEDNEWS)}
 </related_news>
</page>
{response.contenttype("text/xml")} 
</se:xhtmlpage>

Notes:

  • This results in an XML with elements such as <page> and <nr>. The example format is much like the RAW channel format. In practice the format will be agreed with the third party that consumes the XML.
  • Compared to the XML output of the RAW channel several fields are omitted: technical fields, security related fields, fields related to content management, and more. This is also in accordance with the interface definition to be agreed with the third party.
  • The use of {itemdata.rawfield(...)} rather than {itemdata.field(...)} results in field data without executing SXML.
  • {html.cdata(...)} is added to produce XML CDATA blocks whenever the field may contain data that disrupts the XML syntax, such as an & ampersand.
  • Fields are addressed by a direct viper method such as {itemdata.name()}, a logical field name such as {itemdata.rawfield(Summary)}, or by a physical field name such as {itemdata.rawfield(body)}. This is the order from most preferred to least preferred.
  • Fields for thesaurus terms and fields for item relations are supported by the translations described below.

Resulting XML

A news items may for example result in the following XML document:

XML CopyCode image Copy Code
<?xml version="1.0" encoding="utf-8" ?>
<page>
    <nr type="xsd:int">9477</nr>
    <title type="xsd:string"><![CDATA[Smartsite iXperion 1.3 released]]></title>
    <contenttype type="xsd:string">NWS</contenttype>
    <text type="xsd:string"><![CDATA[<p>...</p>]]></text>
    <summary type="xsd:string"><![CDATA[...]]></summary>
    <adddate type="xsd:dateTime">2010-09-20T12:26:55</adddate>
    <code type="xsd:string">GUID-C2FF128C56934FC9A02F4059CC79E61E</code>
    <language thesaurus="LANGUAGES">
        <item key="66" code="LANGUAGE" guid="LANGUAGE_5"><![CDATA[English]]></item>
        <item key="67" code="LANGUAGE" guid="LANGUAGE_8"><![CDATA[Dutch]]></item>
    </language>
    <related_news contentrelation="RELATEDNEWS">
        <item nr="3457" code="GUID-ACD4BC81974742F18C858E0E6D3440EE">Smartsite iXperion 1.2 released</item>
        <item nr="3458" code="GUID-2AE3EBF9D3B34B698E820194C9FCC3BC">Planned future releases</item>
    </related_news>
</page>

Auxiliary translations

The viper {itemdata.rawfield(...)} could be used if the field involves thesaurus terms or related items. The result is a datatable, yet to be formatted in order to produce XML. The datatable may however not contain all the required information, as is the case for thesaurus terms, or may contain more information than required, as is the case for item relations.

Instead two auxiliary translations are used. One translation produces a list of thesaurus terms.

Translation XmlThesaurusTerms(ItemNr, ThesaurusCode, LogicalFieldName):

Smartsite SXML CopyCode image Copy Code
<se:sqlquery save="Result">
 <se:parameters>
  <se:parameter name="sql">
   SELECT tt.Nr, tt.Name, tt.Code, tt.GUID
   FROM ContentsThesTerms ctt
   JOIN ContentTypeFields ctf ON ctt.nrContentTypeField=ctf.Nr
   JOIN ThesTerms tt ON ctt.nrThesTerms=tt.Nr
   JOIN Thesauri t ON tt.ThesaurusNr=t.Nr
   WHERE ctt.nrContents=?:ItemNr
   AND t.Code=?:ThesaurusCode
   AND ctf.Name=?:LogicalFieldName
  </se:parameter>
        <se:parameter name="params">
            <se:collection>
                <se:member name="ItemNr">{translation.arg(ItemNr)}</se:member>
                <se:member name="ThesaurusCode">{translation.arg(ThesaurusCode)}</se:member>
                <se:member name="LogicalFieldName">{translation.arg(LogicalFieldName)}</se:member>
            </se:collection>
        </se:parameter>
  <se:parameter name="format">
   <se:rowformat>
    <item key="{this.field(Nr)}" code="{this.field(Code)}" guid="{this.field(Guid)}">{html.cdata(this.field(Name))}</item>
   </se:rowformat>
  </se:parameter>
  <se:parameter name="resultformat">{this.result()}</se:parameter>
 </se:parameters>
</se:sqlquery>
{translation.setresult(sys.iif($Result EQ null, '', $Result))}

The second translation produces the list of related items.

Translation XmlContentRelations(ItemNr,RelationTypeCode):

Smartsite SXML CopyCode image Copy Code
<se:sqlquery save="Result">
 <se:parameters>
  <se:parameter name="sql">
   SELECT a.Nr, a.Code, a.Title
   FROM ContentRelations cr
   JOIN vwActive a ON cr.nrTo=a.Nr
   WHERE cr.nrFrom=?:ItemNr
   AND cr.nrType=(SELECT Nr FROM ContentRelationTypes WHERE Code=?:RelationTypeCode)
   UNION
   SELECT a.Nr, a.Code, a.Title
   FROM ContentRelations cr
   JOIN vwActive a ON cr.nrFrom=a.Nr
   WHERE cr.nrTo=?:ItemNr
   AND cr.nrType=(SELECT Nr FROM ContentRelationTypes WHERE Code=?:RelationTypeCode)
  </se:parameter>
        <se:parameter name="params">
            <se:collection>
                <se:member name="ItemNr">{translation.arg(ItemNr)}</se:member>
                <se:member name="RelationTypeCode">{translation.arg(RelationTypeCode)}</se:member>
            </se:collection>
        </se:parameter>
  <se:parameter name="format">
   <se:rowformat><item nr="{this.field(Nr)}" code="{this.field(Code)}">{html.cdata(this.field(Title))}</item>{char.crlf()}</se:rowformat>
  </se:parameter>
  <se:parameter name="resultformat">{this.result()}</se:parameter>
 </se:parameters>
</se:sqlquery>
{translation.setresult(sys.iif($Result EQ null, '', $Result))}

Further automation

So far this is a complete example.

The approach requires the XML render templates to be written by hand, one render template per contenttype of interest. The main business rule implemented by the render templates is however the decision which fields should be part of the XML output. This could be configured by means of a contenttype field property. All other information could be inferred:

  • The XML element name, using the logical field name or using the physical field name.
  • The datatype such as int or string.
  • When to produce thesaurus relations or item relations.

---