I want to verify if a certain JSON key exists in the JSON datastore that I use inside the Word template.
This is the JSON:
{
"dummy": "text",
"customers": {
"label": {
"name": "name-of-the-group"
},
"label2": {
"name": "name-2-of-the-group"
}
}
}
In Word I tried to use
<<if [_data.customers.contains(“label2”)]>> Label2 is present<<else>>Label2 is missing<</if>>
<<if [_data.customers.contains(“label3”)]>> Label3 is present<<else>>Label3 is missing<</if>>
but then it prints
Label2 is missing
Label3 is missing
although label2 is present.
And when I try to use
<<if [_data.customers.label3 != null]>> Label3 is present<<else>>Label3 is missing<</if>>
then I get
<<if [_data.customers.label3 != Error! Can not get the value of member 'label3' on type 'class com.aspose.words.internal.zzjq'. null]>> Label3 is present<<else>>Label3 is missing<</if>>
Can anyone provide me with an example how to check if a JSON key exists?
@bottemav You can use the following syntax:
<<if [_data.customers.label2 != null]>>Label2 is present<<else>>Label2 is missing<</if>>
<<if [_data.customers.label3 != null]>>Label3 is present<<else>>Label3 is missing<</if>>
But you should enable ReportBuildOptions.ALLOW_MISSING_MEMBERS
:
JsonDataSource ds = new JsonDataSource("C:\\Temp\\data.json");
Document doc = new Document("C:\\Temp\\in.docx");
ReportingEngine engine = new ReportingEngine();
engine.setOptions(ReportBuildOptions.ALLOW_MISSING_MEMBERS);
engine.buildReport(doc, ds, "_data");
doc.save("C:\\Temp\\out.docx");
Thanks. That works.
A related question: is there a method to retrieve the keys of the customers JSON object?
@bottemav
Do you need this ability within a template document or for your programming code?
@ivan.lyagin In the template document
@bottemav
Unfortunately, there is no simple way to do this. However, this is doable in principle. Internally, JsonDataSource
is mapped to com.aspose.words.net.System.Data.*
classes. The following code snippet uses this fact and shows the basic idea on how to get JSON properties and values dynamically:
String template = "Simple properties: " +
"<<foreach [in getTable().getColumns().where(c => !c.getColumnName().startsWith(\"_\"))]>>" +
"<<[getColumnName()]>> = <<[getTable().getRows().get(0).get(getColumnName())]>>, " +
"<</foreach>>" +
"Nested properties: " +
"<<foreach [in getTable().getDataSet().getRelations().where(r => r.getParentTable() == getTable())]>>" +
"<<foreach [in getChildTable().getColumns().where(c => !c.getColumnName().startsWith(\"_\"))]>>" +
"<<[getColumnName()]>> = <<[getTable().getRows().get(0).get(getColumnName())]>>, " +
"<</foreach>>" +
"<</foreach>>";
DocumentBuilder builder = new DocumentBuilder();
builder.write(template);
String json = "{ prop1:\"value1\", prop2:\"value2\", nestedObj:{ nestedProp1:\"nestedValue1\" } }";
ByteArrayInputStream stream = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8));
ReportingEngine engine = new ReportingEngine();
engine.buildReport(builder.getDocument(), new JsonDataSource(stream));
System.out.print(builder.getDocument().getText());
Note the condition with startsWith("_")
, it is required to skip system columns.
The template can be made less verbose if using a custom class providing shortcuts as static methods accepting com.aspose.words.net.System.Data.DataTable
, com.aspose.words.net.System.Data.DataRelation
, etc. See Setting up Known External Types for more information.