Skip to main content
Solved

How to coerce attribute type for JSONTemplater?


Forum|alt.badge.img
In a JSONTemplater I am using fme:get-attribute to insert the value of an attribute created in the workspace with an AttributeCreator.

 

 

The attribute is a represents a status code, so it should be interpreted as an integer, however the JSONTemplater always interprets it as a string, despite all my attempts at forcing it to integer.

 

 

Using @int(fme:get-attribute("_statuscode")) results in a TCL error (apparently the @int function is being evaluated before the fme:get-attribute function).

 

 

Also tried using an ExpressionEvaluator with @int(1.0) but this is still interpreted as a string.

 

 

Any ideas? Thanks!

Best answer by mark2atsafe

Hi folks,

 

I got an answer to this directly from the developer.

 

 

Hope it's useful

 

 

Mark

 

 

---------------------------------------------

 

 

The short answer is: use an XQuery type cast, in this case xs:int, like so:

 

 

{

 

    "status" : xs:int( fme:get-attribute("int_attr") )

 

}

 

 

The longer answer is this:

 

 

The fme:get-attribute function will return a value whose type corresponds to the underlying type of the FME attribute.  In this case, the attribute is likely a string attribute.  This can be checked by using a Logger transformer.

 

 

A 'cast' can be used to convert a string value to an integer.  The syntax is quite simple, xs:int( "132" ).  Strings can be converted to quite a few numeric types, but for JSON, the most useful casts will be:

 

  • xs:int
  • xs:double
Using something like @int will probably not work, as the TCL is executed before the XQuery.  In addition, the use of Tcl or FME functions within a JSON/XML template will have a severe negative effect on the performance of the transformer.

 

View original
Did this help you find an answer to your question?

11 replies

david_r
Evangelist
  • May 15, 2013
Hi,

 

 

strictly speaking, JSON is untyped, so a string representation is actually the correct way of transferring your numeric values.

 

 

Is there any particular reason for needing to transfer these otherwise?

 

 

David

david_r
Evangelist
  • May 15, 2013
Just in case, here is a workaround using a PythonCaller to cast an attribute into an integer in FME:

 

 

-----

 

import fmeobjects   def FeatureProcessor(feature):

 

    attribName = "status" # Modify here     value = feature.getAttribute(attribName)     try:         feature.setAttribute(attribName, int(value))     except:         pass

 

-----

 

 

It will silently ignore all type errors.

 

 

David

fmelizard
Contributor
Forum|alt.badge.img+17
  • Contributor
  • May 15, 2013
Hi,

 

 

True JSON is text, you can always try the string formatter on your attribute.

 


david_r
Evangelist
  • May 15, 2013
Hi Itay,

 

 

I tried the StringFormatter before posting, it didn't make any difference in this scenario, FME still considers the result as a string :-)

 

 

David

fmelizard
Contributor
Forum|alt.badge.img+17
  • Contributor
  • May 15, 2013
Ha David,

 

 

Hurry Python saves the day, but I do feel like we are treading water.....:)

david_r
Evangelist
  • May 15, 2013
Yes, I agree that the PythonCaller feels like overkill in this situation, but I can't see any other way.

 

 

FME really should have an AttributeTypeCoercer :-)

Forum|alt.badge.img
  • Author
  • May 15, 2013
David, the PythonCaller technique worked great, thanks!

 

 

JSON actually has several data types including numbers, strings, booleans and nulls, and the JSONTemplater seems to automatically use the right type for attributes brought in from readers, it's just attributes created in the workspace that seem to always be interpreted as strings byt he JSONTemplater.

 

 

I wonder what is different about the PythonCaller vs. my ExpressionEvaluator attempt (other than that one is Python and the other is TCL).

fmelizard
Contributor
Forum|alt.badge.img+17
  • Contributor
  • May 15, 2013
Good to know about those data types, dont use JSON that much hence the glitch.....I would also like to know why python does the job, but TCL (expression evaluator and string formatter) wont.

 

Regards,

 

Itay

mark2atsafe
Safer
Forum|alt.badge.img+43
  • Safer
  • Best Answer
  • May 27, 2013
Hi folks,

 

I got an answer to this directly from the developer.

 

 

Hope it's useful

 

 

Mark

 

 

---------------------------------------------

 

 

The short answer is: use an XQuery type cast, in this case xs:int, like so:

 

 

{

 

    "status" : xs:int( fme:get-attribute("int_attr") )

 

}

 

 

The longer answer is this:

 

 

The fme:get-attribute function will return a value whose type corresponds to the underlying type of the FME attribute.  In this case, the attribute is likely a string attribute.  This can be checked by using a Logger transformer.

 

 

A 'cast' can be used to convert a string value to an integer.  The syntax is quite simple, xs:int( "132" ).  Strings can be converted to quite a few numeric types, but for JSON, the most useful casts will be:

 

  • xs:int
  • xs:double
Using something like @int will probably not work, as the TCL is executed before the XQuery.  In addition, the use of Tcl or FME functions within a JSON/XML template will have a severe negative effect on the performance of the transformer.

 


jorge_vidinha
Contributor
Forum|alt.badge.img+2
  • Contributor
  • September 17, 2017
mark2atsafe wrote:
Hi folks,

 

I got an answer to this directly from the developer.

 

 

Hope it's useful

 

 

Mark

 

 

---------------------------------------------

 

 

The short answer is: use an XQuery type cast, in this case xs:int, like so:

 

 

{

 

    "status" : xs:int( fme:get-attribute("int_attr") )

 

}

 

 

The longer answer is this:

 

 

The fme:get-attribute function will return a value whose type corresponds to the underlying type of the FME attribute.  In this case, the attribute is likely a string attribute.  This can be checked by using a Logger transformer.

 

 

A 'cast' can be used to convert a string value to an integer.  The syntax is quite simple, xs:int( "132" ).  Strings can be converted to quite a few numeric types, but for JSON, the most useful casts will be:

 

  • xs:int
  • xs:double
Using something like @int will probably not work, as the TCL is executed before the XQuery.  In addition, the use of Tcl or FME functions within a JSON/XML template will have a severe negative effect on the performance of the transformer.

 

Thanks, usefull. Question: Is there something in FME modern to cast json txt:int ? Or this still be the pratical way of doing it.

 

 


takashi
Contributor
Forum|alt.badge.img+19
  • Contributor
  • September 18, 2017
mark2atsafe wrote:
Hi folks,

 

I got an answer to this directly from the developer.

 

 

Hope it's useful

 

 

Mark

 

 

---------------------------------------------

 

 

The short answer is: use an XQuery type cast, in this case xs:int, like so:

 

 

{

 

    "status" : xs:int( fme:get-attribute("int_attr") )

 

}

 

 

The longer answer is this:

 

 

The fme:get-attribute function will return a value whose type corresponds to the underlying type of the FME attribute.  In this case, the attribute is likely a string attribute.  This can be checked by using a Logger transformer.

 

 

A 'cast' can be used to convert a string value to an integer.  The syntax is quite simple, xs:int( "132" ).  Strings can be converted to quite a few numeric types, but for JSON, the most useful casts will be:

 

  • xs:int
  • xs:double
Using something like @int will probably not work, as the TCL is executed before the XQuery.  In addition, the use of Tcl or FME functions within a JSON/XML template will have a severe negative effect on the performance of the transformer.

 

It's a syntax conforming to the XQuery/XPath specifications (a kind of global standard). According to the specifications, as far as I know, this is the proper and only way to cast data types in XQuery expressions, including XML/JSON template expressions that can be processed with FME transformers.

 


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings