views:

664

answers:

2

I'm regularly creating an XSD schema by transforming a proprietary data model of a legacy system. This works out pretty good. However, the legacy system only allows me to specify very basic attributes of a parameter, such as the data type (int, string etc.).

I would like to enhance the XSL transformation with a mechanism that allows me to add meta data in order to provide more details for the transformation. I thought of something like the Java properties notation to assign attributes to an XPath.

Imagine the following example:

legacy system data model (acutally that neat, but suits best for demonstration purposes)

<datamodel>
  <customer>
    <firstName type="string"/>
    <lastName type="string"/>
    <age type="int">
  <customer>
</datamodel>

meta data

customer/firstName/@nillable=false
customer/lastName/@nillable=false
customer/age/@nillable=true
customer/firstName/@minOccurs=1
customer/firstName/@maxOccurs=1
customer/lastName/@minOccurs=1
customer/lastName/@maxOccurs=1

resulting XSD schema

...
<xs:complexType name="customerType">
  <xs:sequence>
    <xs:element name="firstName" type="xs:string" nillable="false" minOccurs="1" maxOccurs="1"/>
    <xs:element name="lastName" type="xs:string" nillable="false" minOccurs="1" maxOccurs="1"/>
    <xs:element name="age" type="xs:int" nillable="true"/>
  </xs:sequence>
</xs:complexType>
...

What do you think of that? Is there a way to include meta data into an XSL stylesheet?

+1  A: 

"What do you think of that?"

TwoThree things.

  1. Fix the legacy metadata. It's XML. Add stuff to it. Add a namespace if you have to.

  2. If you can't fix the legacy metadata, who will maintaint he second set of metadata that isn't in XML notation? Who will do the double-entry of making a metadata change? What are the odds of anyone following through?

  3. Consider using XML for the additional metadata, not pseudo-XPath. Consistency will help those that come after you figure out what's going on.

S.Lott
1) okay, to be honest: The legacy system is closed source without any chance of fiddling with the data model generation code and not as neat as described above. However, that's good enough for demonstration purposes. 2) I'm aware of the downsides when it comes to maintenance
poezn
+1  A: 

The best solution would be to modify the legacy data by adding the missing metadata.

An instance of the modified "datamodel" vocabulary may be something like this:

<datamodel xmlns:nm="my:new.meta">
    <customer>
     <firstName type="string"
                nm:nillable="false"
                nm:minOccurs="1"
                nm:maxOccurs="1"
                />
     <lastName type="string"
               nm:nillable="false"
               nm:minOccurs="1"
               nm:maxOccurs="1"
               />
     <age type="int" nm:nillable="true"/>
    </customer>
</datamodel>

Putting the new properties in a separate namespace is a good way to easily distinguish them from the already supported properties. Usually using attributes in a namespace is not recommended, so if this is to be avoided, one could use sub-elements (belonging to the new namespace) instead of attributes. Making the new attributes belong to a different namespace may result in the legacy schema validation not to reject them.

If due to some reasons it is not possible to modify the legacy data, I would recommend not to include the new properties in the XSLT stylesheet itself (this is perfectly possible, for example as defining this as the contents of a global <xsl:variable>), but to provide these new properties as a separate XML file or as a set of one ore more XML files.

Any XML file may be accessed dynamically during an XSLT transformation using the XSLT document() function. An instance of the XML file with the new properties may look like this:

<newProperties xmlns:nm="my:new.meta">
    <customer>
     <firstName nm:nillable="false"
                nm:minOccurs="1"
                nm:maxOccurs="1"
                />
     <lastName nm:nillable="false"
               nm:minOccurs="1"
               nm:maxOccurs="1"
               />
     <age nm:nillable="true"/>
    </customer>
</newProperties>

Hope this helped.

Cheers,

Dimitre Novatchev

Dimitre Novatchev