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}}
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 toHaruki
. - Example: The definition
{{Contact.Id}}
Resolves to123456
(the internal contact identifier).
Multiple entities can be related to a single value.
- Example: The definition
{{Contact.Account.Field(M_CompanyName)}}
resolves toEloqua
.
Field values can also be combined.
- Example: The definition "Mr.
{{Contact.Field(C_FirstName)}}
{{Contact.Field(C_LastName)}}
" Resolves to "Mr. Haruki Murakami
".
/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')+ ;