How to check if a JSON key exists using LINQ Reporting Engine?

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.