In an earlier post, I alluded to AML (Adaptive Markup Language) as the "secret sauce" of Innovator.  Most enterprise systems claim some level of XML support, but Innovator takes it a few steps further.  XML, in the form of the AML dialect, is built in at the very core of Innovator.  Exchanging AML with the Innovator server is literally the only way to perform any operation in Innovator.  You may not always see it happening, but AML is behind every transaction you perform using the client, every piece of business logic and every integration with another system.

You may be wondering why you should care about this.  After all, every system has some sort of protocol that you could theoretically use to perform transactions, etc.  The difference is that AML is simple, easy to learn and extensible.  Sure, there are few quirks here and there, but keep reading and you'll understand a large portion of the traffic that goes between the Innovator client (in the browser) and the server.  If you choose to, you can then form your own AML and use it to run Innovator without using our client at all.

There are really only a few tags that you need to know to get started with AML.  The first, appropriately enough, is the <AML> tag.  This serves as the top level of an AML document, and may contain one or more <Item> tags.  <Item> tags may contain one or more property tags (named after the properties) and a <Relationships> tag, which in turn may contain one or more <Item> tags.  Got that?  Okay, maybe some examples might help.  When reading the examples, keep in mind that everything in Innovator is an Item and every Item has a type (its ItemType name).  Please also note that permissions are checked on every request and an error will be returned if the requested operation is not valid for the current user.

The following AML will retrieve a Part Item with a known id:

<AML> <Item type="Part" action="get" id="F48DB69482994831BC26314A1586B39E"/> </AML>

Breaking this down, you should note that the <Item> tag has three attributes: type, action and id.  In this case, the type is "Part", but it could just as easily have been "Document" or "Process Plan" or even "ItemType".  In other words, you can get any Item in Innovator with this form of AML.  Theaction attribute is set to "get" in this case.  Other actions include "add", "update" and "delete".  By specifying an id, we know that this transaction is for a single item with a unique id.  When this AML is submitted, the Innovator server will return AML with more detail (including the properties of the requested item), like this:

<Item type="Part" typeId="4F1AC04A2B484F3ABA4E20DB63808A88" id="F48DB69482994831BC26314A1586B39E" page="1" pagemax="1" itemmax="1"> <state>Preliminary</state> <name>Widget Assembly</name> <item_number>1000</item_number> … (more properties) </Item>

If you don't happen to know the id of the item you're looking for, property values in the request can be used as search criteria, like this:

<AML> <Item type="Part" action="get"> <item_number>1000</item_number> </Item> </AML>

This AML will return the same as above, assuming there is only one Part with an item_number of "1000".  Let's say you want to get both the Part item and its BOM (Bill of Materials).  You would then use the <Relationships> tag to specify the relationships you're looking for, like this:

<AML> <Item type="Part" action="get"> <item_number>1000</item_number> <Relationships> <Item type="Part BOM" action="get"/> </Relationships> </Item> </AML>

The structure of the response from the server would then look like this (properties removed for clarity):

<Item type="Part" id="F48DB69482994831BC26314A1586B39E"> <item_number>1000</item_number> <Relationships> <Item type="Part BOM" id="0A2746E857BA4BFCB606FF447919A9E0"> <quantity>10</quantity> <related_id> <Item type="Part" id="DF3822B9D0CD4C6991F5800161D9B48D"> <item_number>1001</item_number> </Item> </related_id> </Item> <Item type="Part BOM" id="6F5E747AC2F84108B41E0576F73E9466"> <quantity>2</quantity> <related_id> <Item type="Part" id="E2B9A29631074C8F94F25FC93C74AAB6"/> <item_number>1002</item_number> </Item> </related_id> </Item> </Relationships> </Item>

Note that the top-level Part item contains a <Relationships> tag, which contains 2 Part BOM items.  Each Part BOM item then has a related_idproperty, which contains the child Part item.  So, the response is telling you that Part 1000 has a BOM that includes Part 1001 (quantity 10) and Part1002 (quantity 2).  This response is showing a single-level BOM, but a multi-level one would simply have relationships under Parts 1001 and 1002.  The repeated Item / Relationships / Item / related_id pattern is a hallmark of AML.

Other actions, like "add", work similarly.  So this AML:

<AML> <Item type="Part" action="add"> <item_number>1003</item_number> </Item> </AML>

Simply creates a new Part and sets its item_number to "1003".  The response from the server is similar to that of a "get" request, and includes data that is set automatically by the server, like id and state:

<Item type="Part" typeId="4F1AC04A2B484F3ABA4E20DB63808A88" id="57D2BD8E6BC34A8C85E54242C88FD205" page="1" pagemax="1" itemmax="1"> <state>Preliminary</state> <item_number>1003</item_number> … (more properties) </Item>

That should be enough to give you an idea of what it's all about.  So how then do you use this information?  It depends on your purposes, of course, but you could write your own Innovator client, connect Innovator to another web service, use XSLT to transform AML to another dialect, hook Innovator into your own application, etc.  We'll look at some of these topics in future posts.

Related:
Technical