Show TOC

XML Templating in SAPUI5Locate this document in the navigation structure

XML templating lets you use an XML view as a template.

Overview

This XML view, or template, is transformed by an XML preprocessor on the source level, that is, the XML DOM at runtime, just before an SAPUI5 control tree is created from that XML source.

In the simple example below, the label texts and binding paths come from SAP Annotations for OData Version 2.0 (http://www.sap.com/Protocols/SAPData) such as sap:semantics, and OData Version 4.0 annotations such as com.sap.vocabularies.UI.v1.Badge; much more complex tasks are possible.

This transformation only happens if a preprocessor for XML is requested when the view is created, such as in the following sample (lines 2 and 3). This preprocessor can be given one or more models along with a corresponding binding context (lines 4 and 7; this concept actually exists for any SAPUI5 control's constructor). Typically, an OData model's meta model is given, along with the meta context corresponding to a data path.

In the example, sPath = "/ProductSet('HT-1021')/ToSupplier" and the corresponding meta context point to "/dataServices/schema/0/entityType/0" (the entity type BusinessPartner). The resulting view is bound to the data path within the OData model in order to display the supplier of that product.

Example:

Calling the XML Preprocessor
var oTemplateView = sap.ui.view({
    preprocessors: {
      xml: {
        bindingContexts: {
          meta: oMetaModel.getMetaContext(sPath)
        },
        models: {
          meta: oMetaModel
        }
      }
    },
    type: sap.ui.core.mvc.ViewType.XML,
    viewName: "sap.ui.core.sample.ViewTemplate.tiny.Template"
  });
 
oTemplateView.setModel(oModel);
oTemplateView.bindElement(sPath);
The XML preprocessor traverses the view's XML DOM in a depth-first, parent-before-child manner and does the following:
  • All XML attributes which represent an available binding, that is, a binding based only on models available to the preprocessor, are replaced by the result of that binding. Formatters and so on can be used as with any SAPUI5 binding.

  • XML fragments are inlined; that is, the reference is replaced by the fragment's XML DOM and preprocessing takes place on that DOM as well.

  • The <template:with>, <template:if> and <template:repeat> instructions are processed.

Example:

Component.js

In the Explored app in the demo kit, see the simple but complete example of templating in "XML Templating: minimal sample" based on OData Version 4.0 annotations. It consists of the following three pieces.

  • A component controller that creates an OData model (line 17), waits for the meta model to be loaded (line 28) and then creates a template view (line 29) as its content. A preprocessor for XML is requested (line 31) and settings are passed to it, namely the meta model and the binding context that identifies the starting point within that model. The resulting view is bound to the actual data (model and path).

  • A template view that includes a fragment twice (line 20 and 25) to demonstrate how to reuse code.

  • An XML fragment that demonstrates a simple test (line 10), using expression binding.

Caution

The OData model is based on GWSAMPLE_BASIC and will not work unless a suitable proxy for back-end access is used. For simplicity, no mock data is included in this example.

For more information, see the Help topic, Sample Service - Basic.

/*!
 * ${copyright}
 */
 
/**
 * @fileOverview Application component to display supplier of "/ProductSet('HT-1021')"
 *   from GWSAMPLE_BASIC via XML Templating.
 * @version @version@
 */
jQuery.sap.declare("sap.ui.core.sample.ViewTemplate.scenario.Component");
jQuery.sap.require("sap.ui.model.odata.AnnotationHelper");
 
sap.ui.core.UIComponent.extend("sap.ui.core.sample.ViewTemplate.tiny.Component", {
    metadata : "json",
 
    createContent : function () {
        var oModel = new sap.ui.model.odata.v2.ODataModel(
                "proxy/sap/opu/odata/IWBEP/GWSAMPLE_BASIC/", {
                annotationURI : "proxy/sap/opu/odata/IWFND/CATALOGSERVICE;v=2"
                    + "/Annotations(TechnicalName='ZANNO4SAMPLE_ANNO_MDL',Version='0001')/$value",
                json : true,
                loadMetadataAsync : true
            }),
            oMetaModel = oModel.getMetaModel(),
            sPath = "/ProductSet('HT-1021')/ToSupplier",
            oViewContainer = new sap.m.VBox();
 
        oMetaModel.loaded().then(function () {
            var oTemplateView = sap.ui.view({
                    preprocessors: {
                        xml: {
                            bindingContexts: {
                                meta: oMetaModel.getMetaContext(sPath)
                            },
                            models: {
                                meta: oMetaModel
                            }
                        }
                    },
                    type: sap.ui.core.mvc.ViewType.XML,
                    viewName: "sap.ui.core.sample.ViewTemplate.tiny.Template"
                });
 
            oTemplateView.setModel(oModel);
            oTemplateView.bindElement(sPath);
            oViewContainer.addItem(oTemplateView);
        });
 
        // Note: synchronously return s.th. here and add content to it later on
        return oViewContainer;
    }
});
<mvc:View
    xmlns="sap.m"
    xmlns:core="sap.ui.core"
    xmlns:form="sap.ui.layout.form"
    xmlns:mvc="sap.ui.core.mvc"
    xmlns:template="http://schemas.sap.com/sapui5/extension/sap.ui.core.template/1">
 
    <!-- "meta" model's binding context MUST point to an entity type -->
    <template:with path="meta>com.sap.vocabularies.UI.v1.Badge" var="badge">
        <form:SimpleForm>
            <form:title>
                <core:Title text="{path: 'badge>HeadLine', formatter: 'sap.ui.model.odata.AnnotationHelper.format'}"/>
            </form:title>
 
            <Label text="{path: 'badge>Title/Label', formatter: 'sap.ui.model.odata.AnnotationHelper.format'}"/>
            <Text text="{path: 'badge>Title/Value', formatter: 'sap.ui.model.odata.AnnotationHelper.format'}"/>
 
            <Label text="{path: 'badge>MainInfo/Label', formatter: 'sap.ui.model.odata.AnnotationHelper.format'}"/>
            <template:with path="badge>MainInfo" var="field">
                <core:Fragment fragmentName="sap.ui.core.sample.ViewTemplate.tiny.Field" type="XML"/>
            </template:with>
 
            <Label text="{path: 'badge>SecondaryInfo/Label', formatter: 'sap.ui.model.odata.AnnotationHelper.format'}"/>
            <template:with path="badge>SecondaryInfo" var="field">
                <core:Fragment fragmentName="sap.ui.core.sample.ViewTemplate.tiny.Field" type="XML"/>
            </template:with>
        </form:SimpleForm>
    </template:with>
</mvc:View>
<core:FragmentDefinition
    xmlns="sap.m"
    xmlns:core="sap.ui.core"
    xmlns:template="http://schemas.sap.com/sapui5/extension/sap.ui.core.template/1">
 
    <!-- "field" MUST point to a com.sap.vocabularies.Communication.v1.DataField -->
    <HBox>
        <template:with path="field>Value" helper="sap.ui.model.odata.AnnotationHelper.resolvePath" var="target">
            <!-- go to entity type's property and check SAP Annotations for OData Version 2.0 -->
            <template:if test="{= ${target>sap:semantics} === 'tel'}" >
                <core:Icon src="sap-icon://phone" width="2em"/>
            </template:if>
        </template:with>
        <Text text="{path: 'field>Value', formatter: 'sap.ui.model.odata.AnnotationHelper.format'}"/>
    </HBox>
</core:FragmentDefinition>

The result is equivalent to the following handwritten XML view. Any references to the meta model are gone. Type information has been inserted into the bindings and an "odata.concat" expression for badge>MainInfo/Value has been processed by sap.ui.model.odata.AnnotationHelper.format, concatenating the company name and legal form.

<mvc:View xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:form="sap.ui.layout.form" xmlns:mvc="sap.ui.core.mvc">
  <form:SimpleForm>
    <form:title>
      <core:Title text="{path : 'BusinessPartnerID', type : 'sap.ui.model.odata.type.String', constraints : {'maxLength':'10','nullable':'false'}}"/>
    </form:title>
    <Label text="Name"/>
    <Text text="{path : 'CompanyName', type : 'sap.ui.model.odata.type.String', constraints : {'maxLength':'80'}} {path : 'LegalForm', type : 'sap.ui.model.odata.type.String', constraints : {'maxLength':'10'}}"/>
    <Label text="Phone"/>
    <HBox>
      <core:Icon src="sap-icon://phone" width="2em"/>
      <Text text="{path : 'PhoneNumber', type : 'sap.ui.model.odata.type.String', constraints : {'maxLength':'30'}}"/>
    </HBox>
    <Label text="Web"/>
    <HBox>
      <Text text="{path : 'WebAddress', type : 'sap.ui.model.odata.type.String', constraints : {}}"/>
    </HBox>
  </form:SimpleForm>
</mvc:View>
Summary
Overall, XML templating is based on:
  • Preprocessing instructions such as <template:if>, which can be used inside XML views.

  • An OData meta model which offers a unified access to both, OData v2 metadata and OData v4 annotations.

  • A set of OData type implementations which add knowledge of OData types to SAPUI5.

  • Expression binding which facilitates the use of expressions instead of custom formatter functions

  • The helper class sap.ui.model.odata.AnnotationHelper that offers formatter and helper functions to be used inside XML template views. It knows about the OData meta model and helps with standard tasks like accessing a label or providing a runtime binding path. It brings in the OData types, along with their facets. Its output uses expression binding, if needed.