views:

85

answers:

3

I want to allow users to upload files with transaction information to my application. I want users to be able to user their own file format when doing so (XML or CSV).

So I'm going to need a transformation from their format to my format before doing further processing. I don't want to have to create this XSLT manually every time a user has a new file format, so I want to create a UI to essentially build this XSLT document.

This is relatively easy for a CSV file format. The user says the first element maps to x field on my side, second element maps to 7 field etc.

This gets more complicated when the file format is XML with nested elements etc. Does anyone know of a good UI paradigm for doing so? Any examples I can look at on the web or elsewhere? I imagine the user would have to describe a full xpath as part of the mapping, or maybe first upload an XSD and use that to select elements for the mapping (after which I'd need to generate the XSLT).

I appreciate any ideas.

+1  A: 

If the input XML can be mapped to your XML format in a straight-forward way, then a set of XPath expressions would be required from the user.

By "straight-forward way" I mean a very basic <xsl:apply-templates> approach. The input XML must have individual records that can be addressed unambiguously, containing all the data in the right format. No data would require calculating or other special processing any more complex than what can be achieved by the evaluation of a single XPath expression.

If the input is:

<root>
  <entry id="1" name"foo">
    <data1>somevalue
      <data2>othervalue</data2>
    </data1>
  </entry>
</root>

and your desired output would be:

<records>
  <record>
    <id>1</id>
    <name>foo</name>
    <data1>somevalue</data1>
    <data2>othervalue</data2>
  </record>
</records>

then the user would have to provide the following mappings:

  • root element: "root"
  • record element: "entry"
  • id: "@id"
  • name: "@name"
  • data1: "data1"
  • data2: "data1/data2"

and the XSLT would be something like this (the values in "%" are to be replaced by the actual XPath expressions from the above mapping configuration):

<xsl:template match="/">
  <records>
    <xsl:apply-templates select="%root element%/%record element%" />
  </records>
</xsl:template>

<xsl:template match="%root element%/%record element%">
  <record>
    <id>
      <xsl:value-of select="%id-xpath%[1]" />
    </id>
    <name>
      <xsl:value-of select="%name-xpath%[1]" />
    </name>
    <!-- and so on -->
  </record>
</xsl:template>
Tomalak
A: 

If I understand correctly, you are thinking about the UI needed to create the xslt you need. I'm making an assumption that this is a web based application. One approach would be to use xslt that renders the input xml as html (the one I tend to use is xmlverbatim). You could modify this xslt to create links to nodes. Additionally, you could use some xslt to generate the xpath for that element and make this part of the link. I use this (posted by Jeni Tennison to the XSL-List years ago)

  <xsl:for-each select="ancestor-or-self::*">
    <xsl:text />/<xsl:value-of select="name()" />
    <xsl:text />[<xsl:number />]<xsl:text />
  </xsl:for-each>

Having done that you would have a visual rendering of the xml (rather like the views given by MSIE and Firefox) but with additional links back to your application. Your users could then select the nodes of interest. They have then provided you with the xpaths you need without having to actually write it themselves.

Generating the xslt if you have the xpaths is considerably easier. Tomalek's suggestion above seems a valid way. If you don't actually need xml as the final output, you might be better simply using an xml parser that allows you select nodes given an xpath.

This would become more complex if the information you are receiving contains an arbitrary number of records of course. If this is the case you could use a multi-stage approach and use the technique I've roughed out above to extract a record from the input and then use the approach to identify the individual fields within the record.

Nic Gibson
A: 

Altova MapForce is a commercial product for mapping one XML schema to another and generating an XSL transformation.

You might want to have a look at their trial version and see how they solved this rather complex problem.

0xA3