Specifying JSON attribute through a variable in preprocessing

0 votes
asked Nov 6, 2021 in Wanted features by dragondive (480 points)

In the JSON preprocessing, I want to specify the attribute through a variable and not "hardcode" it in the preprocessor code. I tried using the %eval() function like below, but it doesn't work. How can I achieve this? Is there another approach?

@startuml
!$foo = { "company": "Skynet", "employees" : [
  {"name" : "alice", "salary": 100 },
  {"name" : "bob", "salary": 50} ]
}
start
!$attribute1="name"
!$attribute2="salary"
:The salary of <u>%eval("$foo.employees[0]." + $attribute1)</u> is <u>%eval("$foo.employees[0]." + $attribute2)</u>;
@enduml
commented Nov 6, 2021 by Martin (8,360 points)
edited Nov 6, 2021 by Martin

Not a serious answer, but I spent so long playing with it that I might as well paste it and maybe it could give you some ideas (I basically wrote a simplistic JSON parser in the macro language!):

(click for source)

More seriously, one way for @Plantuml to support what you need could be for %get_variable_value(string) to be able to get JSON extracts.  Currently it doesn't:

@startuml
!$foo = { "company": "Skynet", "employees" : [
  {"name" : "alice", "salary": 100 },
  {"name" : "bob", "salary": 50} ]
}
:$foo.company;
:%get_variable_value("$foo.company");
@enduml

1 Answer

+1 vote
answered Nov 7, 2021 by The-Lu (63,920 points)

Hello D., M., and other,

No need of `%eval()`, just use square bracket, as:

@startuml
!$foo = { "company": "Skynet", "employees" : [
  {"name" : "alice", "salary": 100 },
  {"name" : "bob", "salary": 50} ]
}
start
!$attribute1="name"
!$attribute2="salary"
:The salary of <u>$foo.employees[0][$attribute1]</u> is <u>$foo.employees[0][$attribute2]</u>;
@enduml


See also, my similar question, from last year:
 - https://forum.plantuml.net/11143/data-structures-json-access-json-data-directly-redirection

This functionality is not well documented; I just update the doc. now.

If that can help,
Regards,
Th.

commented Nov 7, 2021 by plantuml (294,960 points)

Thanks Théo !

We've just updated the official site.

@Martin: your JSON parser is amazing!

Some feature in the preprocessor are missing (string replacement? regex? ) so please tell us if you need something.

commented Nov 7, 2021 by kirchsth (4,880 points)

Hello,

you can have foreach access too

@startuml

!include https://raw.githubusercontent.com/kirchsth/C4-PlantUML/extended/C4_Component.puml

AddPersonTag("teamred", $bgColor="#red", $legendText ="member of team red")
AddPersonTag("teamblue", $bgColor="#blue", $legendText ="member of team blue")

!$data={"partlen": "2", "game": "GamePlantuml", "participants": [
{"name": "XYZ" ,"as": "xyz", "team": "A", "persons": ["A1", "A2", "A3"] },
{"name": "RST" ,"as": "rst", "team": "B", "persons": ["B1", "B2" ]},
{"name": "UVW" ,"as": "uvw", "team": "B", "persons": ["B2", "B3" ]}],
"color": {"A": "red", "B": "blue"}
}

!foreach $part in $data.participants
  Component($part.name, $part.as, "techn")
  !foreach $member in $part.persons
    !$teamTag = "team"+$data.color[$part.team]
    Person($member, $member, $tags = $teamTag)
    Rel($member, $part.name, "develop")
  !endfor
!endfor

SHOW_LEGEND()
@enduml

BR Helmut

...