AML Enhancements in OData

This section describes enhancements to AML in the OData interface that enable you to retrieve information about extended properties and classes. You can also filter items by extended class or extended property definition. These enhancements have been introduced as part of the Extended Classification feature.

To request the value of a specific extended property, you need to include the xProperty name in a $select request:

GET http://host/server/odata/Part(‘048…3BC’)?$select=xp-cost 
AML:
<Item type="Part” action="get” id="048…3BC” select="xp-cost($value)” />
Response:
HTTP/1.1 200 OK
{
 "@odata.context": “http://host/server/odata/$metadata#Part(xp-cost)/$entity”,
 "@odata.id": “Part(‘0486…23BC’)”,
 “xp-cost": "{defined xp-cost value}",
 “itemtype": “4F1AC04A2B484F3ABA4E20DB63808A88"
}

Use OData annotations to request an attribute associated with an extended property, as shown in the following example:

GET http://host/server/odata/Part(‘048…3BC’)?$select=xp-cost@aras.permission_id 
AML:
<Item type="Part” action="get” id="048…3BC” select="xp-cost(@permission_id)” />
Response:
HTTP/1.1 200 OK
{
 "@odata.context": “http://host/server/odata/$metadata#Part(xp-*@aras.permission_id)/$entity”,
 "@odata.id": “Part(‘0486…23BC’)”,
 “xp-text@aras.permission_id": "{Permission_PropertyValue ID}",
 “itemtype": “4F1AC04A2B484F3ABA4E20DB63808A88"
}

If you request both a value and/or more than one attribute associated with the same property, you must combine them into one selection list element in the resulting AML:

GET http://host/server/odata/Part(‘048…3BC’)?$select=xp-cost,xp-cost@aras.permission_id 
AML:
<Item type="Part” action="get” id="048…3BC” select="xp-cost($value,@permission_id)” />
Response:
HTTP/1.1 200 OK
{
 "@odata.context": “http://host/server/odata/$metadata#Part(xp-*@aras.permission_id)/$entity”,
 "@odata.id": “Part(‘0486…23BC’)”, 
 “xp-cost": "{defined xp-cost value}",
 “xp-text@aras.permission_id": "{Permission_PropertyValue ID}",
 “itemtype": “4F1AC04A2B484F3ABA4E20DB63808A88"
}

Use xp- as the property name to request all of the extended properties that are defined for an item:

GET http://host/server/odata/Part(‘048…3BC’)?$select=xp-* 
AML:
<Item type="Part” action="get” id="048…3BC” select="xp-*($value)” />
Response:
HTTP/1.1 200 OK
{
 "@odata.context": “http://host/server/odata/$metadata#Part(xp-cost)/$entity”,
 "@odata.id": “Part(‘0486…23BC’)”,
 “xp-cost": "{defined xp-cost value}",
 “itemtype": “4F1AC04A2B484F3ABA4E20DB63808A88"
 … other Part item extended properties
}

Use is_defined the filter function to filter request results using the extended property definition and how the property is defined (either explicit or through extended class):

GET http://host/server/odata/Part?$filter=is_defined(xp-cost) 
AML:
<Item type="Part” action="get">
 <xp-cost condition="is defined"/>
</Item>
Response:
HTTP/1.1 200 OK
{
 "@odata.context": “http://host/server/odata/$metadata#Part”,
 “value": [
 {
 “id": “048…3BC ",
 “item_number": “Part_with_Defined_xp_cost”,
 “itemtype": “4F1AC04A2B484F3ABA4E20DB63808A88"
 … other Part item properties
 }
 … other Part items with defined xp-cost
 ] 
}

You can request a property that is defined in a specific way:

GET http://host/server/odata/Part?$filter=is_defined(xp-cost,explicit) 
AML:
<Item type="Part” action="get">
 <xp-cost condition="is defined” defined_as="explicit"/>
</Item>
Response:
HTTP/1.1 200 OK
{
 "@odata.context": “http://host/server/odata/$metadata#Part”,
 “value": [
 {
 “id": “048…3BC ",
 “item_number": “Part_with_Defined_xp_cost”,
 “itemtype": “4F1AC04A2B484F3ABA4E20DB63808A88"
 … other Part item properties
 }
 … other Part items with explicitly defined xp-cost
 ] 
}

Use the Negate operation to request items that do not have a specific extended property defined:

GET http://host/server/odata/Part?$filter=not is_defined(xp-cost,class) 
AML:
<Item type="Part” action="get">
 <xp-cost condition="is not defined” defined_as="class"/>
</Item>
Response:
HTTP/1.1 200 OK
{
 "@odata.context": “http://host/server/odata/$metadata#Part”,
 “value": [
 {
 “id": “048…3BC ",
 “item_number": “Part_with_xp_cost_not_Defined_in_Class”,
 “itemtype": “4F1AC04A2B484F3ABA4E20DB63808A88"
 … other Part item properties
 }
 … other Part items with xp-cost not defined via xClass
 ] 
}

To implement the in extended condition, the OData Interface has introduced the in() filter function. This function enables you to request specific information related to an item. In the following example, the first argument is the property name, the second argument is the collection to look in, and the third argument is the property name of the collection element:

GET http://host/server/odata/xPropertyContainerItem?$select=id,itemtype&$filter=in(itemtype,$root/ItemType($select=id; $filter=name eq ‘Part’),'id’) 
AML:
<Item type="xPropertyContainerItem” action="get” select=”name,itemtype”>
 <itemtype condition="in” by=“id">
 <Item type=“ItemType” select=“id">
 <Name condition=“eq">Part</Name>
 </Item>
 </itemtype>
</Item>
Response:
HTTP/1.1 200 OK
{
 "@odata.context": “http://host/server/odata/$metadata#xPropertyContainerItem(id,itemtype)”,
 “value": [
 {
 "@odata.type": "#Part”,
 “id": “048…3BC ",
 “itemtype": “4F1AC04A2B484F3ABA4E20DB63808A88"
 }
 … other xPropertyContainerItem items with Part data_source 
 ] 
}

You can use the in() function with other item types as well:

GET http://host/server/odata/Part?$filter=in(created_by_id,$root/User($select=id; $filter=login_name eq ‘jsmith’),'id’) 
AML:
<Item type="Part” action="get">
 <created_by_id condition="in” by="id">
 <Item type="User” select="id">
 <logon>jsmith</logon>
 </Item>
 </created_by_id>
</Item>
Response:
HTTP/1.1 200 OK
{
 "@odata.context": “http://host/server/odata/$metadata#Part”,
 “value": [
 {
 “id": “048…3BC ",
 “item_number": “Part-1",
 “itemtype": “4F1AC04A2B484F3ABA4E20DB63808A88"
 … other Part item properties
 }
 … other Part items created by User ‘jsmith’
 ] 
}

Use the isof_xclass(‘<class-name-or-id>’) function to filter an item collection by its assigned xClass:

GET http://host/server/odata/Part?$filter=isof_xclass(‘Bolt’) 
AML:
<Item type="Part” action="get">
 <Relationships>
 <Item type="Part_xClass” action="get">
 <related_id>
 <Item type="xClass” action="get">
 <name>Bolt</name>
 </Item>
 </related_id>
 </Item>
 </Relationships>
</Item>
Response:
HTTP/1.1 200 OK
{
 "@odata.context": “http://host/server/odata/$metadata#Part”,
 “value": [
 {
 “id": “048…3BC ",
 “item_number": “Bolt”,
 “itemtype": “4F1AC04A2B484F3ABA4E20DB63808A88"
 … other Part item properties
 }
 … other Part items that are classified by class ‘Bolt’
 ] 
}

If you pass the id string as a function argument, the class id is returned instead of the class name:

GET http://host/server/odata/Part?$filter=isof_xclass(‘F48…3BC’) 
AML:
<Item type="Part” action="get">
 <Relationships>
 <Item type="Part_xClass” action="get">
 <related_id>
 <Item type="xClass” action="get">
 <id>048…3BC</id>
 </Item>
 </related_id>
 </Item>
 </Relationships>
</Item>
Response:
HTTP/1.1 200 OK
{
 "@odata.context": “http://host/server/odata/$metadata#Part”,
 “value": [
 {
 “id": “048…3BC ",
 “item_number": “Bolt”,
 “itemtype": “4F1AC04A2B484F3ABA4E20DB63808A88"
 … other Part item properties
 }
 … other Part items that classified by class (with ID='F48…3BC’)
 ] 
}

Use the isof_xclassordescendants(‘<class-name-or-id>’) function to filter an item collection by its assigned xClass or descendants:

GET http://host/server/odata/Part?$filter=isof_xclassordescendants(‘Bolt’) 
AML:
<Item type="Part” action="get">
 <Relationships>
 <Item type="Part_xClass” action="get">
 <related_id>
 <Item type="xClass” action="getxClassAndAllDescendants">
 <name>Bolt</name>
 </Item>
 </related_id>
 </Item>
 </Relationships>
</Item>
Response:
HTTP/1.1 200 OK
{
 "@odata.context": “http://host/server/odata/$metadata#Part”,
 “value": [
 {
 “id": “048…3BC ",
 “item_number": “Bolt”,
 “itemtype": “4F1AC04A2B484F3ABA4E20DB63808A88"
 … other Part item properties
 }
 … other Part items that classified by class class=’Bolt’ or its subclasses
 ] 
}