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

Hi,
I am producing a WORD file with LINQ.Engine.
Sometimes
saldo.atStrumentiByCodStrum does not contain the currentPrice field. How can I check, and only if it has the field print << [salso.atStrumentiByCodStrum.currentPrezzo.iprzme]: ”#, ## 0.00” >>?

@Blegork

Internally, the engine deserializes JSON objects into ADO.NET objects. Then, you can access members of corresponding ADO.NET objects in a common way. This can be used to check presence of an object member as follows:

const string json = @"{ presentValue: 0 }";
MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json));
JsonDataSource dataSource = new JsonDataSource(stream);

DocumentBuilder builder = new DocumentBuilder();
builder.Writeln("<<if [r.Table.Columns.Contains(\"presentValue\")]>>presentValue<<else>>NO presentValue<</if>>");
builder.Writeln("<<if [r.Table.Columns.Contains(\"missingValue\")]>>missingValue<<else>>NO missingValue<</if>>");

ReportingEngine engine = new ReportingEngine();
engine.BuildReport(builder.Document, dataSource, "r");

Console.WriteLine(builder.Document.GetText());

This prints “presentValue” and “NO missingValue”.

I’m inside a loop. I saw it didn’t work:

<<foreach[saldo in catStrum.children]>>
<<[saldo.codIsin]>>
<<if [saldo.Table.Columns.Contains("missingValue")]>>missingValue<<else>>NO missingValue<</if>>
<</foreach>>

@Blegork

Could you please share sample JSON data, so we could reproduce the issue?

ty

test.zip (2.1 KB)

@Blegork

I have checked data you provided using the following code:

// Here, "json" stands for a string containing data you provided.
MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json));
JsonDataSource dataSource = new JsonDataSource(stream);

DocumentBuilder builder = new DocumentBuilder();
builder.Writeln("<<foreach[saldo in catStrum.children]>>");
builder.Writeln("<<[saldo.codIsin]>>");
builder.Writeln("<<if [saldo.Table.Columns.Contains(\"missingValue\")]>>missingValue<<else>>NO missingValue<</if>>");
builder.Writeln("<</foreach>>");

ReportingEngine engine = new ReportingEngine();
engine.BuildReport(builder.Document, dataSource, "catStrum");

Console.WriteLine(builder.Document.GetText());

It prints “NO missingValue” for every item in a loop. It seems working as expected. Could you please clarify what does not work on your end?

@ivan.lyagin

Thanks for the support so it works. If I put it inside a table it tells me:
com.armundia.v2.shared.exception.ArmundiaException: ‘if’ is not well-formed. A conditional expression should return a Boolean value.
New Microsoft Word Document.docx (12.7 KB)

@Blegork

Judging by the exception type, it seems like you use Java. If this is the case, then template syntax should be adjusted accordingly as follows:

<<if [saldo.getTable().getColumns().contains(\"missingValue\")]>>

If this does not help, please ZIP and attach here the following resources for testing, so we could assist you further:

  • An actual template (without sensitive data)
  • Actual data (without sensitive information)
  • Actual code in a programming language you use to build a report

Thanks for your cooperation.

Hi, I have prepared a test classTestLoopIf.zip (244.3 KB)

@Blegork

I have modified the template according to my previous reply and it seems working as expected. Please check TemplatePropMBTestLoop Modified.docx (247.7 KB). Also, please note that this syntax can be used starting from the 21.11 version of Aspose.Words for Java, so you may need to upgrade.

Thanks for the help. I have another question. How can I check:

<<if [saldo.atStrumentiByCodDivtr.getTable().getColumns().contains("currentPrezzo")]>><<[saldo.atStrumentiByCodDivtr.currentPrezzo.iprzme] :”#,##0.00”>><</if>>

or

<<if [saldo.getTable().getColumns().contains("atStrumentiByCodDivtr.currentPrezzo")]>><<[saldo.atStrumentiByCodDivtr.currentPrezzo.iprzme] :”#,##0.00”>><</if>>

?

TemplatePropMBTestLoop.docx (247.9 KB)

@Blegork

Skipping technical details, you can use another template syntax to fulfill your requirement:

<<if [getTable().getDataSet().getTables().get("atStrumentiByCodDivtr").getColumns().contains("currentPrezzo")]>>

This syntax should work almost everywhere in a template. I have modified your last template to show this. Please check TemplatePropMBTestLoop Modified.docx (247.8 KB).

1 Like

@ivan.lyagin

Thanks a lot, but it doesn’t seem to work properly. The if constructor always goes into the else bra
nch, even when the currentPrezzo field exists. I am attaching a simplified version of the json file

testWordJson.zip (239.1 KB)

@Blegork

I have modified your last template as well as JSON data to test both cases - when currentPrezzo is missing and present. Please check testModified.zip (238.9 KB).

As a note, the template became heavy, so may I wonder why do you wrap <<[saldo.atStrumentiByCodDivtr.currentPrezzo.iprzme] :”#,##0.00”>> with an if tag? Is it because without wrapping, an exception is thrown?