Hi Folks,
For the past week I have been using MapForce. It is a fun and neat tool for mapping data. However, I have encountered some challenges with it, which I describe below. Perhaps those people on the list who are experienced with MapForce can identify where I am not understanding correctly? /Roger
--------------------------------------------------------------
I have location data to 6 digits precision (i.e., 6 digits past the decimal point). I want to fuzz the location data to 2 digits precision. Plus I want to preserve size. Thus, the last 4 digits will be set to zeroes. For example, I want to map this location data:
<location>
<altitude>30000</altitude>
<latitude>42.364978</latitude>
<longitude>-71.022362</longitude>
</location>
to this:
<location>
<altitude>30000</altitude>
<latitude>42.360000</latitude>
<longitude>-71.020000</longitude>
</location>
Notice that the latitude and longitude values have been fuzzed and size is preserved.
Here’s how I did the mapping: MapForce has a “round-precision” component that rounds a decimal number to the number of digits you specify (I specified 2). And it has a “format-number” component which formats a number according to a pattern (I specified 000.000000 as the pattern). Here is the mapping that I created using MapForce:
Goodness’s
The mapping is done graphically by simply dragging components from a palette onto a canvas and then wiring the components together. No coding. No programming.
This is good.
Once you’re done creating the mapping you can auto-generate code. The code can take any input, perform the mapping on it, and generate the output. MapForce does any-to-any mapping and conversion of:
- XML
- JSON
- Database data
- Text and flat files
- Excel
- EDI
- XBRL
- Google Protocol Buffers
- SOAP web services
- REST web services
“What is the programming language of the auto-generated code?”, you ask. Answer: you get to choose the programming language that you want MapForce to generate. MapForce can auto-generate code for any of these languages:
- XSLT (v1, v2, and v3)
- XQuery
- Java
- C#
- C++
This is good.
Challenges
I ran MapForce’s tool to auto-generate code and specified XSLT 2.0 as the desired programming language. When I did so, I got this message:
Recall that I used the “round-precision” component. Well, XSLT doesn’t have a round-precision function (it does have a round function). So, MapForce refused to generate XSLT code for my mapping.
On the other hand, Java, C#, and C++ do have a round-precision function so MapForce happily generated Java, C#, and C++ code.
But I really wanted XSLT code, so I reworked my mapping to use components that I knew are available in XSLT. In my new mapping I did the fuzzing by first applying the format function with pattern 0.00 and then concatenating 0000 onto the result:
Now MapForce happily generated XSLT code. Oddly, format-number is not part of XQuery, so MapForce refused to generate XQuery code. However, it did generate Java, C#, and C++ code.
Lesson Learned: not all the components on the MapForce palette are usable by all the programming languages. So a user of MapForce has to know which components to avoid.
That is a challenge.
Okay, now I’ve auto-generated XSLT code for my mapping (the second mapping, the one that uses concat). Exciting! Let me run it against an input.
I ran the XSLT that MapForce generated on this input:
<location>
<altitude>30000</altitude>
<latitude>42.364978</latitude>
<longitude>-71.022362</longitude>
</location>
It produced this output:
<location>
<altitude>30000</altitude>
<latitude>42.36</latitude>
<longitude>-71.02</longitude>
</location>
Yikes! What happed to the last 4 digits of latitude and longitude?
I examined the XSLT and found out what happened. Before I tell you, however, I need to show you my XML Schema for location:
<xs:element name="location">
<xs:complexType>
<xs:sequence>
<xs:element name="altitude" type="xs:integer" />
<xs:element name="latitude" type="xs:decimal" />
<xs:element name="longitude" type="xs:decimal" />
</xs:sequence>
</xs:complexType>
</xs:element>
Notice that the type for latitude and longitude is xs:decimal. That is important.
As I said, I examined the XSLT. I found that it formats the number first. For example, it formats this latitude:
42.364978
to this:
42.36
Then it concatenates 4 zeroes, which generates this value:
42.360000
And then, since the XML Schema says the value is of type xs:decimal, it casts the value to xs:decimal, which yields this:
42.36
Casting to xs:decimal results in discarding the non-significant trailing 4 digits!
How to fix this? Well, one solution is to modify the XML Schema and specify xs:string as the datatype for latitude and longitude:
<xs:element name="location">
<xs:complexType>
<xs:sequence>
<xs:element name="altitude" type="xs:integer" />
<xs:element name="latitude" type="xs:string" />
<xs:element name="longitude" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
Perhaps there is another solution which doesn’t involve altering my XML Schema?
/Roger