AHEAD LOGO

The XML Composition Tool xc


This document explains the use xc, an XML Composition Tool. The following are the sections of the document:

Constant

For xc a constant is any well-formed XML file that may or not have associated a schema or a DTD  for validation.

The following is a typical example of a constant contained in file constant.xml.

<?xml version="1.0"?>
<!-- constant.xml -->
<!-- An example of a constant file, in this case is AFrame -->
<!-- Last Update: June 23, 2003 -->

<aframe xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="AFrame.xsd"
filename="constant.java">

<func name="imports">
<param name="list" value="default-values"/>

<body>
<while name="x" in="list">
import {$x};
int {$x};
</while>
</body>

</func>

<func name="main">
<param name="arg" value=""/>

<body>
<call name="imports">
<with name="list" value="x.y.z"/>
</call>
</body>

</func>

</aframe>

Function

A function is an extension to a constant file. A well-formed XML file is considered a function if its root element is the tag function and follows the next pattern:

<function xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="XmlFunction.xsd">

... sequence of refinements go here
</function>

A function file consists of a sequence or list of extensions. The order in which they appear, from top to bottom, is the order in which they are applied to the constant file. A function file is validated with the schema XmlFunction.xsd before proceeding to composition. This schema guarantees that the function follows the required structure  that is explained in this section. There are 4 types of extensions refine, before, after, replace. The following sections describe and illustrate them.

Extension refine

This type of extension allows to refine XML code in a similar way to the concept of method extension (overriding) found in traditional Object-Oriented Programming (OOP). In the XML context,  a tag that is extended and its children elements are the equivalent of the method definition and its body. As in the case of OOP, a method can use the super keyword to refer to its parent method (the one that it extends).

Consider the following extension  imports shown below. Let's say we want to add a set tag right after the body tag, and a while tag before the closing body tag. In other words,  the desired composition is the following:

<func name="imports">

<param name="list" value="default-values" />
<body>
<set value="one,two" name="avar" />

<while name="x" in="list">
import {$x};
int {$x};
</while>

<while name="y" in="avar">
System.out.println("{$y}");
</while>


</body>
</func>

The way to achieve this result is shown in function1.xml, and it is as follows: 

<!-- Adds one variable, and an extra while loop to the imports function -->
<refine path="/aframe/func[@name='imports']/body" tag="append" separator=".">
<body>
<set name="avar" value="one,two"/>

<super/>

<while name="y" in="avar">
System.out.println("{$y}");
</while>


</body>

</refine>

Please notice the following details:

Extension before

This form of extension allows a new tag to be added before the occurrence of a set of tags specified by a XPath expression. In other words, a tag in the set specified by a XPath expression has a parent node, the new tag will be inserted as a child of the parent node right before the selected tag.

For example, let's say that we have the following code:

<func name="main">
  <param name="arg" value="" /> 

  <body>
 
    <call name="imports">
      <with name="list" value="x.y.z" />
    </call>
   
   </body>
  
 </func> 

We want to add a new call tag before the current call tag  In other words, we want the output  to look like:

<func name="main">
<param name="arg" value="" />

<body>
<call name="imports">
<with name="list" value="a.b.c"/>
</call>


<call name="imports">
<with name="list" value="x.y.z" />
</call>

</body>

</func>

The way to achieve it is through the following before refinement in the file function1.xml:

<!-- Adds a function call to imports before current call in main -->
<before path="/aframe/func[@name='main']/body/call[@name='imports']">
<call name="imports">
<with name="list" value="a.b.c"/>
</call>
</before>

As with the case of the extensions of type refine, the path attribute specifies the XPath expression that selects the set of tags to which the refinement will be applied. This attribute is required. For further details on definition of XPath expression see [1].

Extension after

It works similarly to the before extension, but instead it adds the new tag after the occurrence of the selected tags. For example, consider the following extension contained in file  function2.xml

<!-- Adds a function call to imports before current call in main -->
<after path="/aframe/func[@name='main']/body/call[@name='imports']">
<call name="imports">
<with name="list" value="abc"/>
</call>

</after>

If  we  apply this extension to our constant file we obtain the following code:

<func name="main">
<param name="arg" value="" />
<body>

<call name="imports">
<with name="list" value="x.y.z" />
</call>

<call name="imports">
<with value="abc" name="list" />
</call>


</body>
</func>

Extension replace

It works in a similar way to before and after extensions.The difference is that instead of inserting a new tag in each of the selected tags specified by the XPath expression, it substitutes these tags with the new tags.  Continuing with our example, assume that we want to substitute the while tag in:

<func name="imports">
<param name="list" value="default-values"/>

<body>
<while name="x" in="list">
import {$x};
int {$x};
</while>

</body>

To look like:

<func name="imports">
<param name="list" value="default-values" />
<body>

<set value="pqrs" name="sequence" />
<while in="sequence" name="i">
System.out.println("var variable" + {$i});
</while>


</body>
</func>

The way to do it is by using the following replace extension contained in function2.xml

<!-- Replaces the while tag inside the body of function imports -->
<replace path="/aframe/func[@name='imports']/body/while">
<set name="sequence" value="pqrs"/>
<while name="i" in="sequence">
System.out.println("var variable" + {$i});
</while>

</replace>

Again the value of the attribute path is an XPath expression that defines the set of nodes that are going to be refined. 

Composition Cases

An XML file can be either a constant or a function. Therefore there are 4 different composition cases that have to be considered:

Command-line Invocation

The following are the command arguments to call the xc:

xc [options] -o outputFile
    -c file1 file2 file3 ...     // composes xml files ...file3(file2 (file1))
    -f file1 file2 file3 ...     // composes files with lists of xml files ...file3(file2 (file1) )

Examples:

1) To compose constant.xml and function1.xml  type:

   xc -c constant.xml function1.xml   -o  output.xml

2) Let files1 be the file:
      constant.xml
      function.xml

     and files2 be:
       function2.xml

    Composed as follows:

    xc -f files1 files2 -o output.xml

     is equivalent to

    xc -c constant.xml function1.xml function2.xml  -o output.xml 

Current implementation limitations

The following is the list of limitations of current version of xc :

Reference 

[1] Harold, Elliot R., Means W.Scott. XML in a Nutshell. Second Edition.O'Reilly & Associates Inc., 2002.


 ATS Home Page

Copyright © Software Systems Generator Research Group. All rights reserved.
Revised: January 25, 2006.