Eloqua markup language version 2

Important: This document discusses Eloqua markup language v2. Learn more about Eloqua markup language v3.

Eloqua markup language (EML) is a text-based language used to access and provide a consistent view of Eloqua data.

EML uses text to identify fields and data relationships for data-centric entities. This way, you can easily describe and access the field values, entity attributes and relations that are important to you, using intuitive language.

Terminology

  • Contact: A contact in the Eloqua system
  • Account: An account or company in the Eloqua system
  • CustomObject: A custom object in the Eloqua system, with its own set of field definitions
  • Field: An attribute of a Contact, Account or Custom Object that has an identifier and an internal name

Access patterns

All statements enclosed in {{ and }} will be resolved if they can be parsed. If there is no available data an empty string will be inserted.

For all entities that can be indexed, indexing is available by ID or system name. The pattern is to use ( and ) to delimit a named index, and [ and ] to delimit an ID index.
Note that because the wrong brackets are used, the following is invalid and cannot be indexed: {{Contact.Field(1000001)}} {{Contact.Field[C_EmailAddress]}}

Related assets are addressed through a "." notation. For example, to get the data for the account name field of the account related to a given contact, you could use the following statement (assuming there is an account field with the internal name M_CompanyName): {{Contact.Account.Field(M_CompanyName)}.

Available entities

EML can access core assets: Contact, Account and Custom Object data.

Note: Access to additional core assets (Event, Campaign response, and Opportunity) were added in Eloqua markup language v3.

Assets related to core assets are available as long as the relationship resolves to a single entity and not many.

Example: Account information can be accessed through a contact since there is at most a single account related to any given contact, it resolves to a single entity. However, it doesn't work the other way around: contact information cannot likely be accessed through an account, as there is usually more than a single associated contact, i.e. {{Contact.Account.Field(M_CompanyName)}} is valid, but {{Account.Contact.Field(C_FirstName)}} is not.

Special fields are available for contact records:

  • Global Subscription information is addressable as: {{Contact.Email.IsSubscribed}}
  • Email Bounceback status is addressable as: {{Contact.Email.IsBounced}}
  • Email Format preference is addressable as: {{Contact.Email.Format}}

Note: When using {{Contact.Email.IsSubscribed}} or {{Contact.Email.IsBounced}} in an export filter or in an import use “0” for False and “1” for True.

Resolution

EML parts are evaluated differently. Below are example resolutions for different EML types.

Field values

Resolves to the appropriate database value.

  • Example: The definition {{Contact.Field(C_FirstName)}} resolves to Haruki.
  • Example: The definition {{Contact.Id}} Resolves to 123456 (the internal contact identifier).

Multiple entities can be related to a single value.

  • Example: The definition {{Contact.Account.Field(M_CompanyName)}} resolves to Eloqua.

Field values can also be combined.

  • Example: The definition "Mr. {{Contact.Field(C_FirstName)}} {{Contact.Field(C_LastName)}}" Resolves to "Mr. Haruki Murakami".
Example: There is a contact field in the system with the below properties. You can retrieve this information by calling a GET request to the "/assets/contact/fields?depth=complete" endpoint.
    
    "type": "ContactField",
    "id": "100001",
    "createdAt": "-2208970800",   
    "depth": "complete", 
    "name": "Email Address",
    "updatedAt": "-2208970800", 
    "dataType": "text",
    "displayType": "text",
    "internalName": "C_EmailAddress",
    "isReadOnly": "false",
    "isRequired": "false",
    "isStandard": "true",
    "isPopulatedInOutlookPlugin": "false",
    "updateType": "always"


The following contact data is retrieved by calling a GET request to the "/data/contact/1" endpoint:

    
    "type":"Contact",
    "currentStatus":"Awaiting action",
    "id":"1",
    "createdAt":"1403034086",
    "depth":"complete",
    "name":"haruki.murakami@oracle.com",
    "updatedAt":"1410193024",
    "emailAddress":"haruki.murakami@oracle.com",
    "emailFormatPreference":"unspecified",
    "fieldValues":[ ... ],
    "firstName":"haruki",
    "isBounceback":"false",
    "isSubscribed":"true",
    "lastName":"murakami",
    "subscriptionDate":"1403034086"

Given the above information, the following EML statements: {{Contact.Field[100001]}} and {{Contact.Field(C_EmailAddress)}} will resolve to the value of the specified field, which in both cases is the contact’s email address: "haruki.murakami@oracle.com". {{Contact.Field(C_EmailAddress)}} references the asset's email address field by its internalName attribute, and {{Contact.Field[100001]}} references the asset's email address by its field id.

Grammar

grammar Eml; 
 
options {  
    language = CSharp3; 
    output = AST;
    backtrack = true;
} 
 
tokens {
    CUSTOMOBJECT_NAME;
    CUSTOMOBJECT_INDEX;
    FIELD_NAME;
    FIELD_INDEX; 
    ACTIVITY_TYPE_ATTRIBUTE;
    ASSET_NAME_ATTRIBUTE;
    ASSET_ID_ATTRIBUTE;
    CAMPAIGN_ID_ATTRIBUTE;
}
 
public dynamicEntity
    : DYNAMICSTART! WS!? ( (relationshipToContact WS!? DOT! WS!? contactAttribute) 
        | (relationshipToAccount WS!? DOT! WS!? accountAttribute) 
        | (relationshipToCustomObject WS!? DOT! WS!? customObjectAttribute) 
        | (relationshipToActivity WS!? DOT! WS!? activityAttribute) 
    ) WS!? DYNAMICEND!
    ;
 
relationshipToContact
    : CONTACT
    | customObject WS!? DOT! WS!? CONTACT
    | ACTIVITY WS!? DOT! WS!? CONTACT
    ;
 
relationshipToAccount
    : ACCOUNT
    | CONTACT WS!? DOT! WS!? ACCOUNT
    | customObject WS!? DOT! WS!? ACCOUNT
    ;
 
relationshipToCustomObject
    : customObject
    ;
 
relationshipToActivity
    : ACTIVITY
  ;
 
contactAttribute
    : field
    | ID_ATTRIBUTE
    | EMAIL! WS!? DOT! WS!? (
        | EMAIL_ISSUBSCRIBED_ATTRIBUTE
        | EMAIL_ISBOUNCED_ATTRIBUTE
        | EMAIL_FORMAT_ATTRIBUTE
    );
 
accountAttribute
    : field
    | ID_ATTRIBUTE
    ;
 
customObjectAttribute
    : field
    | ID_ATTRIBUTE
    ;
 
activityAttribute
    : TYPE_ATTRIBUTE -> ACTIVITY_TYPE_ATTRIBUTE
  | CREATEDAT_ATTRIBUTE
  | CAMPAIGN WS? DOT WS? ID_ATTRIBUTE -> CAMPAIGN_ID_ATTRIBUTE
    | ASSET WS? DOT WS? (
        | NAME_ATTRIBUTE -> ASSET_NAME_ATTRIBUTE
        | ID_ATTRIBUTE -> ASSET_ID_ATTRIBUTE
    );
 
field
    : FIELD WS? ( 
          NAMESTART WS? NAME WS? NAMEEND -> FIELD_NAME NAME
        | INDEXSTART WS? INT WS? INDEXEND -> FIELD_INDEX INT
    );
 
customObject
    : CUSTOMOBJECT WS? (
          NAMESTART WS? NAME WS? NAMEEND -> CUSTOMOBJECT_NAME NAME
        | INDEXSTART WS? INT WS? INDEXEND -> CUSTOMOBJECT_INDEX INT
    );   
 
// Lexer tokens
DYNAMICSTART : '{{' ;
DYNAMICEND   : '}}' ;
INDEXSTART   : '['  ;
INDEXEND     : ']'  ;
NAMESTART    : '('  ;
NAMEEND      : ')'  ;
DOT          : '.'  ;
 
CONTACT                      : 'Contact';
ACCOUNT                      : 'Account';
CUSTOMOBJECT                 : 'CustomObject';
ACTIVITY                     : 'Activity';
FIELD                        : 'Field';
EMAIL                        : 'Email';
ASSET                        : 'Asset';
CAMPAIGN                     : 'Campaign';
ID_ATTRIBUTE                 : 'Id';
EMAIL_ISSUBSCRIBED_ATTRIBUTE : 'IsSubscribed';
EMAIL_ISBOUNCED_ATTRIBUTE    : 'IsBounced';
EMAIL_FORMAT_ATTRIBUTE       : 'Format';
TYPE_ATTRIBUTE               : 'Type';
NAME_ATTRIBUTE               : 'Name';
CREATEDAT_ATTRIBUTE          : 'CreatedAt';
 
NAME : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|' ')* ;
INT  : ('0'..'9')+ ;
WS   : (' '|'\t'|'\n'|'\r')+ ; 

Learn more

Eloqua expression language