Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Universal FetchXML (UFX) is an advanced query language that you can use to query data by using dynamic FetchXML. It shapes and prepares the resulting data for consumption by the Universal Resource Scheduling (URS) solution. This query language enables you to create custom queries to customize and extend the schedule board and schedule assistant filters to meet the unique business needs of the organization.
UFX consists of two components: UFX bag and UFX query.
Simple UFX bag
A UFX bag contains statically typed data. In memory, it models a dictionary with keys and values. You can serialize it to JSON and XML. When the data is typed, a UFX Query can query data from it, and client UI can bind to it.
For practical and performance reasons, the in-memory bag is implemented on top of the Dynamics 365 apps SDK Entity object.
Sample bag containing two values.
In memory:
| key | value | type |
|---|---|---|
| name | John | string |
| age | 36 | int |
In JSON:
{
"name": "John",
"age": 36
}
In XML:
<bag>
<name ufx-type="string">John</name>
<age ufx-type="int">36</age>
</bag>
UFX supported types
A UFX bag can contain values of many types. They're categorized into three type classes:
| Category | Value |
|---|---|
| Simple types | bool (Boolean), int (Int32), long (Int64), double (Double), decimal (Decimal), datetime (DateTime), guid (Guid), string (String)Dynamics 365 specific simple types: money (Money), option (OptionSet), lookup (EntityReference) |
| Other Bags | bag (Entity) |
| List of Bags | list (EntityCollection) |
Here's a sample JSON bag containing more types:
{
"citizen": true, // implicit bool
"age": 36, // explicit int
"age@ufx-type": "int",
"name": { // nested bag
"first": "John",
"last": "Doe"
},
"children": [ // list of bags
{ "name": "Sam" },
{ "name": "Judy" }
]
}
The same bag in XML:
<bag>
<citizen ufx-type="bool">true</citizen>
<age ufx-type="int">36</age>
<name ufx-type="bag">
<first ufx-type="string">John</first>
<last ufx-type="string">Doe</last>
</name>
<children ufx-type="list">
<bag>
<name ufx-type="string">Sam</name>
</bag>
<bag>
<name ufx-type="string">Judy</name>
</bag>
</children>
</bag>
UFX queries
Write UFX queries as XML-based UFX Bags. Properties in the bag can contain UFX directives to query data dynamically. A UFX query executes on in-memory objects, not XML. Only the directives are written in XML. You can serialize its output to JSON or XML.
The following UFX query defines the accounts property in the bag with the source UFX directive. As a result, Dynamics 365 executes the inline FetchXML, populating the accounts property with a list of bags. An EntityCollection where each bag represents an individual account record from Dynamics 365.
<bag xmlns:ufx="https://schemas.microsoft.com/dynamics/2017/universalfetchxml">
<accounts ufx:source="fetch">
<fetch top="10">
<entity name="account" />
</fetch>
</accounts>
</bag>
A UFX Query is processed sequentially and can contain many FetchXML queries.
Here's a snippet of the result of the previous UFX Query serialized to XML. Some values have metadata that further describes them.
<bag>
<accounts ufx-type="list">
<bag ufx-id="166e39dd-34a1-e611-8111-00155d652f01" ufx-logicalname="account">
<accountid ufx-type="guid">166e39dd-34a1-e611-8111-00155d652f01</accountid>
<accountnumber ufx-type="string">ABSS4G45</accountnumber>
<name ufx-type="string">Fourth Coffee (sample)</name>
<statecode ufx-type="option" ufx-formatvalue="Active">0</statecode>
<websiteurl ufx-type="string">https://www.fourthcoffee.com/</websiteurl>
<primarycontactid ufx-type="lookup" ufx-formatvalue="Yvonne McKay (sample)" ufx-logicalname="contact">7c6e39dd-34a1-e611-8111-00155d652f01</primarycontactid>
...
</bag>
<bag ufx-type="bag" ufx-id="186e39dd-34a1-e611-8111-00155d652f01" ufx-logicalname="account">
<accountid ufx-type="guid">186e39dd-34a1-e611-8111-00155d652f01</accountid>
<accountnumber ufx-type="string">ACTBBDC3</accountnumber>
<name ufx-type="string">Litware, Inc. (sample)</name>
<statecode ufx-type="option" ufx-formatvalue="Active">0</statecode>
<websiteurl ufx-type="string">https://www.litwareinc.com/</websiteurl>
<primarycontactid ufx-type="lookup" ufx-formatvalue="Susanna Stubberod (sample)" ufx-logicalname="contact">7e6e39dd-34a1-e611-8111-00155d652f01</primarycontactid>
...
</bag>
...
</accounts>
</bag>
The select UFX directive takes an XPath expression that selects values from the current bag.
<bag xmlns:ufx="https://schemas.microsoft.com/dynamics/2017/universalfetchxml">
<accounts ufx:source="fetch">
<fetch top="10">
<entity name="account" />
</fetch>
</accounts>
<first_account_name ufx:select="accounts/bag[1]/name" />
<!-- null values remove properties from the bag -->
<accounts ufx:select="$null" />
</bag>
The resulting bag in XML:
<bag>
<first_account_name ufx-type="string">Fourth Coffee (sample)</first_acount_name>
</bag>
Certainly the most powerful aspect of a UFX Query is its ability to dynamically generate FetchXML based on input data.
In the following sample, search for accounts by a value supplied by the user and available as a UFX bag through the XPath $input variable. Notice the UFX if and value directives on the condition element.
<bag xmlns:ufx="https://schemas.microsoft.com/dynamics/2017/universalfetchxml">
<accounts ufx:source="fetch">
<fetch top="10">
<entity name="account">
<filter>
<condition attribute="name" operator="like" ufx:if="$input/NameFilter">
<ufx:value select="$input/NameFilter" attribute="value" />
</condition>
</filter>
</entity>
</fetch>
</accounts>
</bag>
If the NameFilter property in the input bag contained %city%, the produced FetchXML condition executed by Dynamics 365 would look like this.
<condition attribute="name" operator="like" value="%city%" />
Keys, values, and metadata
A UFX bag contains keys and values, where some values have more metadata to describe them.
An example might be a value of type lookup (EntityReference). When queried from Dynamics 365 through FetchXML, it returns the logical name of the entity and the formatted display name of the record. The UFX bag preserves this extra information as metadata attached to the primary value.
Serialized to JSON, a lookup with metadata looks like this:
{
"primarycontactid": "7e6e39dd-34a1-e611-8111-00155d652f01",
"primarycontactid@ufx-type": "lookup",
"primarycontactid@ufx-logicalname": "contact",
"primarycontactid@ufx-formatvalue": "Susanna Stubberod (sample)"
}
In XML:
<primarycontactid ufx-type="lookup" ufx-formatvalue="Susanna Stubberod (sample)" ufx-logicalname="contact">7e6e39dd-34a1-e611-8111-00155d652f01</primarycontactid>
XPath over Dynamics 365 data
When you type data in a UFX bag, a UFX query can see it in a structured format and use XPath to traverse the data and select values.
An XPath expression specified in a UFX directive sees the data in the bag similar to the structure of the bag in XML-serialized form. However, the data is stored in in-memory .NET objects (in instances of Entity and EntityCollection types) and not in XML documents.
UFX type reference
All UFX types support the ufx-type and ufx-formatvalue metadata. The following table describes additional metadata for each type.
| UFX Name | Attribute Type Code | .NET Name | UFX Metadata |
|---|---|---|---|
| bool | Boolean | Boolean | |
| int | Integer | Int32 | |
| long | BigInt | Int64 | |
| double | Double | Double | |
| decimal | Decimal | Decimal | |
| datetime | DateTime | DateTime | |
| guid | Uniqueidentifier | Guid | |
| string | Memo | String | |
| money | Money | Money | |
| option | Picklist | OptionSetValue | |
| lookup | Lookup | EntityReference | ufx-logicalname |
| bag | N/A | Entity | ufx-idufx-logicalname |
| list | N/A | EntityCollection | |
| N/A | N/A | AliasedValue | ufx-aliasentityufx-aliasattribute |
UFX query directives
Use UFX directives on bag properties and on XML elements of a FetchXML query.
UFX bag directives
| Attribute | Value | Description |
|---|---|---|
ufx:if |
XPath | Tests the XPath expression and only processes the property if the test returns true |
ufx:source |
fetch |
Executes the inline <fetch> XML element and assigns the result to the property |
ufx:select |
XPath | Executes the XPath expression and assigns the result to the property When querying for a bag or list, you can specify an optional child bag in XML form to transform the result of the XPath expression |
UFX FetchXML directives
| Element | Attribute | Value | Description |
|---|---|---|---|
| All elements | ufx:if |
XPath | Tests the XPath expression and only emits the XML element if the test succeeds |
ufx:apply |
select |
XPath | Loops over the nodeset returned by the XPath expression and outputs the child XML elements once for each node |
ufx:value |
select |
XPath | Executes the XPath expression and outputs the result in the current XML element |
ufx:value |
attribute |
attribute name | Assigns the XPath expression result to the specified attribute name on the current XML element |
UFX XPath functions
UFX adds many new functions in addition to the ones available natively in XPath.
datetime()
datetime(): Returns the current time in UTC.
list()
list(bag | list, ...[bag | list]): Takes a number ofbagorlistvalues as input and flattens them into a singlelist.
lookup-to-list()
lookup-to-list(lookup, ...[lookup]): Takes severallookupvalues, converts each value to abagwith theufx-idandufx-logicalnamemetadata set, and flattens them into a singlelist.
option-to-list()
option-to-list(option, ...[option]): Takes severaloptionvalues, converts each value to abagwith a singleoptionproperty, and flattens them into a singlelist.
order()
order(list, string, bool): Orders a list by a property in eachbag. Specify the property in the second argument, and specify descending order in the third argument.order(list, list): Orders a list by multiple sort orders specified as a list in the second argument. Eachbagin the second list can have anameanddescendingproperty.
iif()
iif(any, any, any): If the first argument is true, returns the second argument. Otherwise, returns the third argument.
UFX XPath variables
| Name | Description |
|---|---|
| $input | A bag available to the UFX query with input values |
| $null | A null constant. Selecting $null on a property removes the property from the bag |
| $current | Reference to the current bag the UFX query is processing |
Additional resources
Understanding and customizing resource matching in Universal Resource Scheduling