Technology Blog Posts by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
MioYasutake
SAP Champion
SAP Champion
1,547

The Problem

When building Fiori Elements apps, you sometimes need to add XML annotations on the UI side. The usual approach is to search for examples in the UI5 Demo Kit. For instance, you might find something like this:

Disabling the Search filter

<Annotations Target="SAP__self.Container/SalesOrder">
   <Annotation Term="SAP__capabilities.SearchRestrictions">
      <Record>
         <PropertyValue Property="Searchable" Bool="false" />
      </Record>
   </Annotation>
</Annotations>

However, simply copying this into your annotation.xml won't work. To figure out what needs to be changed, you need to understand the basic structure of annotations.

 

What You Need to Know

1. Annotation Targets

The target of an annotation varies depending on the annotation you want to apply. Here are the most common ones:

TargetSyntax for Target attributeExample in UI5 Documentation
EntityType{Namespace}.{EntityType}Common for UI annotations (UI.FieldGroup, UI.HeaderInfo, etc.). Note: documentation examples often show only the inner <Annotation> element, omitting the outer <Annotations Target="..."> wrapper.
EntitySet{Namespace}.{EntityContainer}/{EntitySet}TravelService.EntityContainer/Travel [1]
Property{Namespace}.{EntityType}/{Property}Z0020_CDS.Z0020Type/CountryID [3]
NavigationProperty{Namespace}.{EntityContainer}/{EntitySet}/{NavigationProperty}myService.EntityContainer/SalesOrderManage/_Item [2]
Action (Bound){Namespace}.{Action}({BindingParameterType})com.c_salesordermanage_sd.CreateWithSalesOrderType(com.c_salesordermanage_sd.SalesOrderManage) [2]
Action (Unbound){Namespace}.{Action}SAP__self.CreateWithSalesOrderType [2]
Action Parameter{Namespace}.{Action}/{Parameter}SalesOrder.CreateWithSalesOrderType/SalesOrganization [2]
EntityContainer{Namespace}.{EntityContainer}namespace.EntityContainer [4]

[1] Disabling the Editing Status Filter
[2] Actions
[3] In / Out Mappings in the ValueList Annotation
[4] Adapting the Filter Bar

The Namespace, EntityType, EntitySet, and other names used in the Target attribute can all be found in your service's metadata.xml document. When developing a Fiori Elements app, this file is typically located in your project folder.

CAP Example

In a CAP service, open metadata.xml and look for the following:

<Schema Namespace="QuoteService" ...>  <!-- Namespace -->

    <EntityContainer Name="EntityContainer">  <!-- EntityContainer name -->
        <EntitySet Name="Quotations" EntityType="QuoteService.Quotations">  <!-- EntitySet name -->
            <NavigationPropertyBinding Path="attachments" Target="Quotations_attachments"/>
        </EntitySet>
    </EntityContainer>

    <EntityType Name="Quotations">  <!-- EntityType name -->
        <Property Name="Description" Type="Edm.String"/>  <!-- Property name -->
        <NavigationProperty Name="attachments" .../>  <!-- NavigationProperty name -->
    </EntityType>

</Schema>

From this, you can construct your target values:

TargetValue
EntityTypeQuoteService.Quotations
EntitySetQuoteService.EntityContainer/Quotations
PropertyQuoteService.Quotations/Description
NavigationPropertyQuoteService.Quotations/attachments
EntityContainerQuoteService.EntityContainer

RAP Example

In a RAP service, the structure is similar, but notice the Alias attribute on the Schema element:

<Schema Namespace="com.sap.gateway.srvd.dmo.flight_r.v0001" Alias="SAP__self">  <!-- Namespace & Alias -->

    <EntityContainer Name="Container">  <!-- EntityContainer name -->
        <EntitySet Name="Connection" EntityType="...ConnectionType">
            <NavigationPropertyBinding Path="_Flight" Target="Flight"/>
        </EntitySet>
    </EntityContainer>

    <EntityType Name="ConnectionType">  <!-- EntityType name -->
        <Property Name="AirlineID" Type="Edm.String"/>  <!-- Property name -->
        <NavigationProperty Name="_Flight" Type="Collection(...FlightType)"/>  <!-- NavigationProperty name -->
    </EntityType>

</Schema>

In RAP, the Target attribute uses the Alias (SAP__self) instead of the full Namespace. The Alias is always SAP__self in RAP services, so you can use it as-is.

TargetValue
EntityTypeSAP__self.FlightType
EntitySetSAP__self.Container/Flight
PropertySAP__self.FlightType/AirlineID
NavigationPropertySAP__self.ConnectionType/_Flight
EntityContainerSAP__self.Container

Note: The UI5 documentation does not indicate whether an annotation example is based on CAP or RAP. This can be a source of confusion — for example, SAP__self and Container in the Target attribute are RAP conventions, while CAP uses the full Namespace and EntityContainer. Always check your own service's metadata.xml to determine the correct values.

 

2. Annotations require a Reference definition

This is why simply copying a snippet from the documentation into your annotation.xml won't work.

For example, to use the annotation shown at the beginning of this post, you need to add the following Reference:

<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
    <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.xml">
        <edmx:Include Namespace="Org.OData.Capabilities.V1" Alias="Capabilities"/>
    </edmx:Reference>
    ...
</edmx:Edmx>

OData vocabularies used in Fiori Elements are defined in two locations:

Here are the vocabularies you will encounter most often when working with Fiori Elements.

SAP vocabularies

AliasNamespaceURI
UIcom.sap.vocabularies.UI.v1https://sap.github.io/odata-vocabularies/vocabularies/UI.xml
Commoncom.sap.vocabularies.Common.v1https://sap.github.io/odata-vocabularies/vocabularies/Common.xml
HTML5com.sap.vocabularies.HTML5.v1https://sap.github.io/odata-vocabularies/vocabularies/HTML5.xml

OASIS vocabularies

AliasNamespaceURI
CoreOrg.OData.Core.V1https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Core.V1.xml
CapabilitiesOrg.OData.Capabilities.V1https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.xml

Tip: If you want to dig deeper, the vocabulary specification files are available at the URIs listed above. Each annotation term definition includes an AppliesTo attribute, which tells you exactly which target types the annotation can be applied to.

For example, in Org.OData.Capabilities.V1.xml:

<Term Name="SearchRestrictions" Type="Capabilities.SearchRestrictionsType" Nullable="false" AppliesTo="EntitySet Collection">
<Annotation Term="Core.AppliesViaContainer"/>
<Annotation Term="Core.Description" String="Restrictions on search expressions"/>
</Term>

This tells you that SearchRestrictions can be applied to an EntitySet target.

 

Step-by-step: Applying a Documentation Sample to Your annotation.xml

Let's walk through how to actually apply the following annotation — the same one from the beginning of this post — to your own project.

<Annotations Target="SAP__self.Container/SalesOrder">
   <Annotation Term="SAP__capabilities.SearchRestrictions">
      <Record>
         <PropertyValue Property="Searchable" Bool="false" />
      </Record>
   </Annotation>
</Annotations>

 

Step 1: Understand the annotation target

Target="SAP__self.Container/SalesOrder"

This follows the format {Namespace or Alias}.{EntityContainer}/{EntitySet}.

You can look up the exact values in your service's metadata.xml:

  • Replace SAP__self with your service's Namespace (CAP) or keep it as-is (RAP)
  • Replace Container with your EntityContainer name
  • Replace SalesOrder with your EntitySet name

Result:

<Annotations Target="MyService.EntityContainer/MyEntity">
   <Annotation Term="SAP__capabilities.SearchRestrictions">
      <Record>
         <PropertyValue Property="Searchable" Bool="false" />
      </Record>
   </Annotation>
</Annotations>

 

Step 2: Add the Reference

The term SAP__capabilities tells you this is a Capabilities vocabulary annotation. Add the following Reference inside the root <edmx:Edmx> element of your annotation.xml, before the <Annotations> block:

<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">

    <!-- Add the Reference here -->
    <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.xml">
        <edmx:Include Namespace="Org.OData.Capabilities.V1" Alias="Capabilities"/>
    </edmx:Reference>

    <!-- Your annotations go below -->
    <Annotations Target="...">
        ...
    </Annotations>

</edmx:Edmx>

Also, replace the SAP__capabilities prefix in the annotation term with the Alias you defined in the Reference. In this case, SAP__capabilities becomes Capabilities. The final annotation will look like this:

<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
    <edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.xml">
        <edmx:Include Namespace="Org.OData.Capabilities.V1" Alias="Capabilities"/>
    </edmx:Reference>

    <Annotations Target="MyService.EntityContainer/MyEntity">
        <Annotation Term="Capabilities.SearchRestrictions">
            <Record>
                <PropertyValue Property="Searchable" Bool="false" />
            </Record>
        </Annotation>
    </Annotations>
</edmx:Edmx>

 

Conclusion

XML annotations can feel intimidating at first, but there are really just two things you need to get right before applying any annotation from the documentation to your project:

  1. The Target — identify your Namespace, EntityContainer, EntitySet, and other names from your service's metadata.xml file
  2. The Reference — add the correct edmx:Reference for the vocabulary you are using

Once you have these two in place, any annotation snippet you find in the UI5 documentation can be adapted to your project. Happy annotating!