Aras Innovator Platform

4.2 Content Generator Example

This section provides an example Content Generator that constructs a table consisting of a row for each child BOM Part of a selected Assembly. The output will be similar to the following:

The top-most Item Document Element, with name ‘PartBOMTable’ contains two child Document Elements. The first is ‘PartBOMTableHeader’; which is a Container Document Element for Text Document Elements that will provide the top-most header row. The second is another Item Document Element, with name ‘PartItemRow’ that also contains Text Document Elements with values for selected Part Properties. The Document Type XML Schema is as follows:

<xs:element name="PartBOMTable">

  <xs:complexType>

    <xs:complexContent>

      <xs:extension base="aras:itemType">

        <xs:sequence maxOccurs="unbounded">

          <xs:element ref="PartBOMTableHeader" minOccurs="1" maxOccurs="1"/>

          <xs:element ref="PartItemRow" minOccurs="0" maxOccurs="unbounded"/>

        </xs:sequence>

        <xs:attribute name="typeId" type="xs:string" fixed="Part ItemType ID"/>

      </xs:extension>

    </xs:complexContent>

  </xs:complexType>

</xs:element>

 

<xs:element name="PartBOMTableHeader">

  <xs:complexType>

    <xs:sequence>

      <xs:element ref="Text" minOccurs="0" maxOccurs="unbounded"/>

    </xs:sequence>

  </xs:complexType>

</xs:element>

  

<xs:element name="PartItemRow">

  <xs:complexType>

    <xs:complexContent>

      <xs:extension base="aras:itemType">

        <xs:choice maxOccurs="unbounded">

          <xs:element ref="Text" minOccurs="0" maxOccurs="unbounded"/>

        </xs:choice>

        <xs:attribute name="typeId" type="xs:string" fixed="Part ItemType ID"/>

      </xs:extension>

    </xs:complexContent>

  </xs:complexType>

</xs:element>

For more information on how to construct Document Type schema see Section 2.3.

The source code for the Content Generator that produces this output is as follows:

//MethodTemplateName=CSharp:Aras.TDF.ContentGenerator(Strict);

ItemDocumentElement targetItem = targetElement as ItemDocumentElement;

 

if (targetItem != null) {

   targetItem.ClearChilds();

  

   String AML = @"<AML>"

           +"<Item type='Part BOM' action='get'>"

           +"  <source_id>" + targetItem.ItemId + "</source_id>"

           +"  <related_id>"

           +"    <Item type='Part' action='get'/>"

           +"  </related_id>"

           +"</Item>"

           +"</AML>";

          

   DocumentSchemaElement headerElement = (DocumentSchemaElement) this.Factory.NewElement("PartBOMTableHeader");

   TextDocumentElement hd1 = (TextDocumentElement) this.Factory.NewText("Text", "Item #");

   TextDocumentElement hd2 = (TextDocumentElement) this.Factory.NewText("Text", "Name");

   TextDocumentElement hd3 = (TextDocumentElement) this.Factory.NewText("Text", "Make/Buy");

   TextDocumentElement hd4 = (TextDocumentElement) this.Factory.NewText("Text", "Type");

   headerElement.AddChild(hd1);

   headerElement.AddChild(hd2);

   headerElement.AddChild(hd3);

   headerElement.AddChild(hd4);

   targetElement.AddChild(headerElement);

  

   Item bomItems = this.Factory.InnovatorInstance.applyAML(AML);

    int numItems = bomItems.getItemCount();

 

    // Loop through each Catalog Entry and fill the remaining table rows

    for(int i=0; i < numItems; i++)

    {

      Item bomItem = bomItems.getItemByIndex(i);

      Item partItem = bomItem.getPropertyItem("related_id");

      ItemDocumentElement itemElement = (ItemDocumentElement) this.Factory.NewElement("PartItemRow");

      // set item reference

      itemElement.SetItem(partItem);

     

      TextDocumentElement numText = (TextDocumentElement) this.Factory.NewText("Text", partItem.getProperty("item_number"));

      TextDocumentElement nameText = (TextDocumentElement) this.Factory.NewText("Text", partItem.getProperty("name"));

      TextDocumentElement mbText = (TextDocumentElement) this.Factory.NewText("Text", partItem.getProperty("make_buy"));

      TextDocumentElement typeText = (TextDocumentElement) this.Factory.NewText("Text", partItem.getProperty("classification"));

      itemElement.AddChild(numText);

      itemElement.AddChild(nameText);

      itemElement.AddChild(mbText);

      itemElement.AddChild(typeText);

     

      targetElement.AddChild(itemElement);

    } // for() loop over catalog entries

 

} // if (targetItem != null)

  1. The first line of a Content Generator Method must identify the Method Template to use as a comment. In this case, it should be specified as it is in this example –
    //MethodTemplateName=CSharp:Aras.TDF.ContentGenerator(Strict);
  2. The Content Generator in this example is configured with an Item Document Element – PartBOMTable. The parameter ‘targetElement’ is passed to the Content Generator Method as a more generic DocumentElement object. This line casts the object to the expected ItemDocumentElement type. The target Element represents the instance of the Document Element that the Content Generator is executed against.
  3. The check for null is necessary to assure that the cast on the previous line was successful. Trying to cast to a Document Element Type class that is not represented by the type of Document Element will cause an error and the variable will be assigned null.
  4. Content Generators can be executed multiple times, either because they are configured as dynamic or because the author explicitly reruns (refreshes) the Document Element. In these cases, the Content Generator Method is executed again on the associated Document Element. Clearing all previously generated content is therefore necessary. Note that the grammar of the function is wrong. ‘ClearChilds()’ will remove all child content from the document.
  5. The Document Element for the first child element for PartBOMTable is created using the Factory Object. The DocumentSchemaElement class is used for Container Document Elements. The name of the Document Element (‘PartBOMTableHeader’) is passed to the constructor.
  6. For this example, the PartBOMTableHeader Document Element contains Text Document Elements as its children. The next 4 lines create a new TextDocumentElement for the ‘labels’ of the Part BOM Table. The TextDocumentElement constructor is passed the name of the Text Document Element (in this case – ‘Text’) and the text used for the content.
  7. Each Text Document Element is added to the parent PartBOMTableHeader
  8. The PartBOMTableHeader is added to the target Element.
  9. An AML Query is executed to extract the Part Items for the Item linked to the target Element.
  10. A loop to extract each Part Item.
  11. Each Part will be linked to a newly generated Item Document Element with the name PartItemRow.
  12. The Item object returned from the execution of the AML is used to set the link for the PartItemRow Item Document Element. This will create a separate link for each row and likewise, a separate Relationship from the Document to the Part Item.
  13. Like the header, new Text Document Elements are added with text extracted from the selected Part properties.
  14. These Item Document Elements are added to the target Element

In summary, all Content Generator Methods should:

  1. Set the appropriate Method Template
  2. Create a variable that is cast to the appropriate type
  3. Clear the content, if necessary
  4. Modify the target Element and/or add child content as appropriate