Solved

How to get the index number of all list elements and append as an attribute to the list which is generated dynamically?

  • 14 November 2019
  • 13 replies
  • 34 views

I have a dynamically generated list called comments as shown below using json templater and sql creator transformers. List contains several objects and I want to generate id for every object as one of the attribute of the same object.

I also want to set an attribute called solution as a boolean true or false. But the attribute lies inside the object and cant set its data type. Is there any solution for this? I am transferring the data to Mongodb by creating a json file from sql based data.

Capture4.PNG

 

JSON Templater code 2 is -

[fme:get-json-list-attribute("_list{}.commentObj")]

Here after mearging data from Oracle and Mongodb in Feature mearger, I am creating a json object using first json templater using below code -

First JSON Templater code -

{

"user":

{"user":fme:get-attribute("TKT_NOTESUSER"),

"username":fme:get-attribute("fullname_notesuser"),

"_id":fme:get-attribute("mongodb_id")

},

"date": fme:get-attribute("TKT_NOTESDATE"),

"comment" : fme:get-attribute("TKT_NOTES"),

"solution": fme:get-attribute("SOLUTION")

}

After this I am building a dynamic list grouped by some id and passing list to second json templater.Code for this templater is -

[fme:get-json-list-attribute("_list{}.commentObj_")]

So giving me the result json file as a list of objects in json writer as shown in above image.

icon

Best answer by takashi 15 November 2019, 00:23

View original

13 replies

Badge +21

Hi @gauripearl - can you upload this short json as a file also? Easier to create a demo

Hi @gauripearl - can you upload this short json as a file also? Easier to create a demo

sample.json

Hi @gauripearl - can you upload this short json as a file also? Easier to create a demo

hi @sigtill I have added a file called sample.json.

Userlevel 2
Badge +17

Regarding the first question (generate id), it's hard to find an appropriate answer unless knowing what template expression you define in the JSONTemplater.

For the second question (enforce boolean type), you can cast string "true" or "false" to boolean true or false in the template expression with the XML type name "xs:boolean". Just be aware the input "true" and "false" should be lowercase.

Try executing this expression with JSONTemplater. Assuming that the feature attribute called "solution" stores "true" or "false".

{
    "solution1" : fme:get-attribute("solution"),
    "solution2" : xs:boolean(fme:get-attribute("solution"))
}

Regarding the first question (generate id), it's hard to find an appropriate answer unless knowing what template expression you define in the JSONTemplater.

For the second question (enforce boolean type), you can cast string "true" or "false" to boolean true or false in the template expression with the XML type name "xs:boolean". Just be aware the input "true" and "false" should be lowercase.

Try executing this expression with JSONTemplater. Assuming that the feature attribute called "solution" stores "true" or "false".

{
    "solution1" : fme:get-attribute("solution"),
    "solution2" : xs:boolean(fme:get-attribute("solution"))
}

@takashi - Please see my edits in the post. I have added all the details. ID is the user field I want to generate dynamically(1,2,3...etc) based on number of objects in a list.

Thanks you very much for the second solution. It just worked perfectly.

Userlevel 2
Badge +17

Regarding the first question (generate id), it's hard to find an appropriate answer unless knowing what template expression you define in the JSONTemplater.

For the second question (enforce boolean type), you can cast string "true" or "false" to boolean true or false in the template expression with the XML type name "xs:boolean". Just be aware the input "true" and "false" should be lowercase.

Try executing this expression with JSONTemplater. Assuming that the feature attribute called "solution" stores "true" or "false".

{
    "solution1" : fme:get-attribute("solution"),
    "solution2" : xs:boolean(fme:get-attribute("solution"))
}

If you added a Counter to generate ID as count attribute before the first JSONTransformer, I think you could add it to the JSON object with this expression.

{
    "id" : fme:get-attribute("_count"),
    "user": {
        "user" : fme:get-attribute("TKT_NOTESUSER"),
        "username" : fme:get-attribute("fullname_notesuser"),
        "_id" : fme:get-attribute("mongodb_id")
    },
    "date": fme:get-attribute("TKT_NOTESDATE"),
    "comment" : fme:get-attribute("TKT_NOTES"),
    "solution": fme:get-attribute("SOLUTION")
}

If you added a Counter to generate ID as count attribute before the first JSONTransformer, I think you could add it to the JSON object with this expression.

{
    "id" : fme:get-attribute("_count"),
    "user": {
        "user" : fme:get-attribute("TKT_NOTESUSER"),
        "username" : fme:get-attribute("fullname_notesuser"),
        "_id" : fme:get-attribute("mongodb_id")
    },
    "date": fme:get-attribute("TKT_NOTESDATE"),
    "comment" : fme:get-attribute("TKT_NOTES"),
    "solution": fme:get-attribute("SOLUTION")
}

i tried with counter but its giving me a count for 2008 objects as shown in the image. I am converting these object to a list grouped by other parameter to 579 features. The count I want is for id's inside the object after creating a list. It should count the objects inside the list and append that count attribute as a part of object. In above json image comment is my list and it has 3 objects. ID should be for these objects like some incrementing counter like 1,2 and 3. 

Userlevel 2
Badge +17

If you added a Counter to generate ID as count attribute before the first JSONTransformer, I think you could add it to the JSON object with this expression.

{
    "id" : fme:get-attribute("_count"),
    "user": {
        "user" : fme:get-attribute("TKT_NOTESUSER"),
        "username" : fme:get-attribute("fullname_notesuser"),
        "_id" : fme:get-attribute("mongodb_id")
    },
    "date": fme:get-attribute("TKT_NOTESDATE"),
    "comment" : fme:get-attribute("TKT_NOTES"),
    "solution": fme:get-attribute("SOLUTION")
}

You can create multiple count number sequences starting with the same number (e.g. 1) for each group by defining counter name which contains an attribute storing group identifier.

Assuming that the source features have an attribute called "TKT_ID" and you have set it to the Group By parameter in the ListBuilder, try inserting a Counter with this setting before the first JSONTemplater.

0684Q00000ArNCwQAN.png

Userlevel 2
Badge +17

Regarding the first question (generate id), it's hard to find an appropriate answer unless knowing what template expression you define in the JSONTemplater.

For the second question (enforce boolean type), you can cast string "true" or "false" to boolean true or false in the template expression with the XML type name "xs:boolean". Just be aware the input "true" and "false" should be lowercase.

Try executing this expression with JSONTemplater. Assuming that the feature attribute called "solution" stores "true" or "false".

{
    "solution1" : fme:get-attribute("solution"),
    "solution2" : xs:boolean(fme:get-attribute("solution"))
}

Alternatively, this workflow with just a single JSONTemplater could work as well.

Root Template:

{
    "json_featuretype" : "pp",
    "TKT_ID" : fme:get-attribute("TKT_ID"),
    "comments" : [
        fme:process-features("SUB")
    ]
}

Sub Template:

{
    "id" : fme:get-attribute("_count"),
    "user" : {
        "user" : fme:get-attribute("TKT_NOTESUSER"),
        "username":fme:get-attribute("fullname_notesuser"),
        "_id":fme:get-attribute("mongodb_id")
    },
    "date": fme:get-attribute("TKT_NOTESDATE"),
    "comment" : fme:get-attribute("TKT_NOTES"),
    "solution": xs:boolean(lower-case(fme:get-attribute("SOLUTION")))
}

0684Q00000ArMo8QAF.png

Alternatively, this workflow with just a single JSONTemplater could work as well.

Root Template:

{
    "json_featuretype" : "pp",
    "TKT_ID" : fme:get-attribute("TKT_ID"),
    "comments" : [
        fme:process-features("SUB")
    ]
}

Sub Template:

{
    "id" : fme:get-attribute("_count"),
    "user" : {
        "user" : fme:get-attribute("TKT_NOTESUSER"),
        "username":fme:get-attribute("fullname_notesuser"),
        "_id":fme:get-attribute("mongodb_id")
    },
    "date": fme:get-attribute("TKT_NOTESDATE"),
    "comment" : fme:get-attribute("TKT_NOTES"),
    "solution": xs:boolean(lower-case(fme:get-attribute("SOLUTION")))
}

0684Q00000ArMo8QAF.png

Hi @takashi

This is working perfectly fine but the format I am getting is little different as shown below, its the comments array inside the comments array..how to get only one comment array

0684Q00000ArNFWQA3.png

Userlevel 2
Badge +17

Hi @takashi

This is working perfectly fine but the format I am getting is little different as shown below, its the comments array inside the comments array..how to get only one comment array

Could you please post the template expressions - Root and Sub - you defined?

Could you please post the template expressions - Root and Sub - you defined?

@takashi - I was able to correct it. I had made a mistake while defining.

Thank you for your help.

Regarding the first question (generate id), it's hard to find an appropriate answer unless knowing what template expression you define in the JSONTemplater.

For the second question (enforce boolean type), you can cast string "true" or "false" to boolean true or false in the template expression with the XML type name "xs:boolean". Just be aware the input "true" and "false" should be lowercase.

Try executing this expression with JSONTemplater. Assuming that the feature attribute called "solution" stores "true" or "false".

{
    "solution1" : fme:get-attribute("solution"),
    "solution2" : xs:boolean(fme:get-attribute("solution"))
}

@takashi  In similar way to force boolean datatype, can we force date as a data type here?

My date attribute is in the string format in final json.

Reply