Skip to main content
Question

Commvault Workflow How to convert JSON to HTML Table

  • February 22, 2026
  • 1 reply
  • 21 views

Forum|alt.badge.img

Hi Team,

 

Here is what I am trying to do - 

 

Example Workflow Sequence

  1. JSONToResultSet

    • Input: JSON string (e.g., from an API or workflow variable)
    • Output: resultSet
  2. ResultSetToHTML

    • Input: resultSet (from previous step)
    • Output: htmlTable
  3. Email

    • Body: Insert variable for htmlTable
    • Format: HTML

 

What I get in the email - 

 

JSON in HTML Tables.. Effectively Junk…

 

If you want to follow along (Locate {YOURCommserveURL},{YOURServersEMAILADDRESS}, {YourEMAILADDRESS} and change before importing) - 

 

<?xml version="1.0" encoding="UTF-8"?>
<Workflow_WorkflowDefinition outputs="<outputs /&gt;" webHidden="0" isHtmlDescription="0" inputs="&lt;inputs /&gt;" interactive="0" description="" manualPercentageComplete="0" apiMode="0" executeOnWeb="0" variables="&lt;variables /&gt;" revision="$Revision:  $" tags="" uniqueGuid="48bb19cf-4d95-43d0-bf71-b58f31ce7db6" name="Daily Backup Report Testing" config="&lt;configuration /&gt;">
  <schema>
    <outputs className="" type="" name="outputs" />
    <variables className="" type="" name="variables" />
    <inputs className="" type="" attribute="0" name="inputs" />
    <config className="" type="" name="configuration" />
  </schema>
  <Start displayName="Start" interactive="0" originalStyle="" jobMode="0" description="" waitSetting="0" continueOnFailure="0" commented="0" height="36" created="0" breakpoint="0" uniqueName="Start_1" skipAttempt="0" name="Start" width="58" x="45" y="41" style="image;image=/images/jgraphx/house.png">
    <inputs val="&lt;inputs /&gt;" />
    <transition sourceX="72" sourceY="59" activity="HttpClient_1" targetY="116" targetX="237" originalStyle="" description="" points="" x="0" y="0" transitionIndex="0" style="defaultEdge" commented="0" status="0">
      <condition script="/*&#xA;The expression should return a boolean. Use the variable name &quot;activity&quot; to refer to the previous activity object. Example:&#xA;activity.exitCode==0;&#xA;*/&#xA;" />
    </transition>
  </Start>
  <Activity displayName="HttpClient" interactive="0" originalStyle="" jobMode="0" description="performs http operations" waitSetting="0" continueOnFailure="0" namespaceUri="commvault.cte.workflow.activities" commented="0" height="34" created="1770612538350" breakpoint="0" uniqueName="HttpClient_1" skipAttempt="0" name="HttpClient" width="100" x="184" y="253" style="label;image=commvault.cte.workflow.activities.HttpClientActivity">
    <inputs val="&lt;inputs&gt;&lt;request&gt;&lt;url&gt;https://{YOURCommserveURL}/commandcenter/api/cr/reportsplusengine/datasets/2638c3d3-adc7-4b61-bb24-2ba509229bf5:a30bd278-c7d9-470f-9ae9-8b4922743330/data&lt;/url&gt;&lt;method&gt;GET&lt;/method&gt;&lt;postType&gt;Raw&lt;/postType&gt;&lt;postContent&gt;&lt;/postContent&gt;&lt;postContentType&gt;application/xml; charset=UTF-8&lt;/postContentType&gt;&lt;parameters&gt;&lt;name&gt;orderby&lt;/name&gt;&lt;value&gt;[JobId] Desc&lt;/value&gt;&lt;/parameters&gt;&lt;parameters&gt;&lt;name&gt;parameter.JobStatus[]&lt;/name&gt;&lt;value&gt;Running,Delayed,Failed,No Run,Killed,Completed with Errors,Completed with Warnings,Committed&lt;/value&gt;&lt;/parameters&gt;&lt;parameters&gt;&lt;name&gt;parameter.timeframe&lt;/name&gt;&lt;value&gt;&#x9;-PT24H P0D&lt;/value&gt;&lt;/parameters&gt;&lt;parameters&gt;&lt;name&gt;parameter.useCSTimeZone&lt;/name&gt;&lt;value&gt;-2&lt;/value&gt;&lt;/parameters&gt;&lt;parameters&gt;&lt;name&gt;parameter.WindowStartTime&lt;/name&gt;&lt;value&gt;00:00:00&lt;/value&gt;&lt;/parameters&gt;&lt;parameters&gt;&lt;name&gt;parameter.datasource[]&lt;/name&gt;&lt;value&gt;2&lt;/value&gt;&lt;/parameters&gt;&lt;headers&gt;&lt;name&gt;Authtoken&lt;/name&gt;&lt;value&gt;QSDKONLY xpath:{/workflow/system/token}&lt;/value&gt;&lt;/headers&gt;&lt;headers&gt;&lt;name&gt;Accept&lt;/name&gt;&lt;value&gt;application/json&lt;/value&gt;&lt;/headers&gt;&lt;/request&gt;&lt;/inputs&gt;" />
    <transition sourceX="237" sourceY="116" activity="JSONToResultSet_1" targetY="381" targetX="180" originalStyle="" description="" points="" x="0" y="0" transitionIndex="0" style="defaultEdge" commented="0" status="0">
      <condition language="4" script="/*&#xA;The expression should return a boolean. Use the variable name &quot;activity&quot; to refer to the previous activity object. Example:&#xA;activity.exitCode==0;&#xA;*/&#xA;" />
    </transition>
  </Activity>
  <Activity displayName="Email" interactive="0" originalStyle="" jobMode="0" description="Sends an email to a list of users" waitSetting="0" continueOnFailure="0" namespaceUri="commvault.cte.workflow.activities" commented="0" height="34" created="1770613083665" breakpoint="0" uniqueName="Email_1" skipAttempt="0" name="Email" width="100" x="909" y="256" style="label;image=commvault.cte.workflow.activities.EmailActivity">
    <inputs val="&lt;inputs&gt;&lt;email&gt;&lt;from&gt;Galaxy@{YOURServersEMAILADDRESS}&lt;/from&gt;&lt;to&gt;{YourEMAILADDRESS}z&lt;/to&gt;&lt;cc /&gt;&lt;bcc /&gt;&lt;subject&gt;Fulton Hogan Daily Backup Report&lt;/subject&gt;&lt;attachments /&gt;&lt;repeatInterval /&gt;&lt;body&gt;&amp;lt;div style=&quot;background-color: white; background-image: null; background-repeat: repeat; background-attachment: scroll; background-position: null; padding-top: 20px; padding-right: 20px; padding-bottom: 20px; padding-left: 20px&quot;&amp;gt;&amp;#xD;&#xD;&#xA;      &amp;lt;h2 align=&quot;left&quot; style=&quot;margin-top: 0&quot;&amp;gt;&amp;#xD;&#xD;&#xA;        Commvault Cloud Software Status&amp;#xD;&#xD;&#xA;      &amp;lt;/h2&amp;gt;&amp;#xD;&#xD;&#xA;      &amp;lt;div style=&quot;padding-top: 12px; padding-right: 12px; padding-bottom: 12px; padding-left: 12px; margin-top: 10px; margin-bottom: 10px; margin-right: 0; margin-left: 0; background-color: #fafafa; background-image: null; background-repeat: repeat; background-attachment: scroll; background-position: null; border-left-color: #4a90e2; border-left-style: solid; border-left-width: 5px&quot;&amp;gt;&amp;#xD;&#xD;&#xA;        &amp;lt;div&amp;gt;&amp;#xD;&#xD;&#xA;          CommVault:&amp;#xD;&#xD;&#xA;        &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;        &amp;lt;div style=&quot;margin-top: 4px&quot;&amp;gt;&amp;#xD;&#xD;&#xA;          xpath:{/workflow/ResultSetToHTML_1/output}&amp;#xD;&#xD;&#xA;        &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;      &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;      &amp;lt;div style=&quot;padding-top: 12px; padding-right: 12px; padding-bottom: 12px; padding-left: 12px; margin-top: 10px; margin-bottom: 10px; margin-right: 0; margin-left: 0; background-color: #fafafa; background-image: null; background-repeat: repeat; background-attachment: scroll; background-position: null; border-left-color: #4a90e2; border-left-style: solid; border-left-width: 5px&quot;&amp;gt;&amp;#xD;&#xD;&#xA;        &amp;lt;div&amp;gt;&amp;#xD;&#xD;&#xA;          Missed SLA:&amp;#xD;&#xD;&#xA;        &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;        &amp;lt;div style=&quot;margin-top: 4px&quot;&amp;gt;&amp;#xD;&#xD;&#xA;          &amp;#xD;&#xD;&#xA;        &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;      &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;      &amp;lt;div style=&quot;padding-top: 12px; padding-right: 12px; padding-bottom: 12px; padding-left: 12px; margin-top: 10px; margin-bottom: 10px; margin-right: 0; margin-left: 0; background-color: #fafafa; background-image: null; background-repeat: repeat; background-attachment: scroll; background-position: null; border-left-color: #4a90e2; border-left-style: solid; border-left-width: 5px&quot;&amp;gt;&amp;#xD;&#xD;&#xA;        &amp;lt;div&amp;gt;&amp;#xD;&#xD;&#xA;          Aux Tape Backup:&amp;#xD;&#xD;&#xA;        &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;        &amp;lt;div style=&quot;margin-top: 4px&quot;&amp;gt;&amp;#xD;&#xD;&#xA;          &amp;#xD;&#xD;&#xA;        &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;      &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;      &amp;lt;div style=&quot;padding-top: 12px; padding-right: 12px; padding-bottom: 12px; padding-left: 12px; margin-top: 10px; margin-bottom: 10px; margin-right: 0; margin-left: 0; background-color: #fafafa; background-image: null; background-repeat: repeat; background-attachment: scroll; background-position: null; border-left-color: #4a90e2; border-left-style: solid; border-left-width: 5px&quot;&amp;gt;&amp;#xD;&#xD;&#xA;        &amp;lt;div&amp;gt;&amp;#xD;&#xD;&#xA;          Aux Disk Backup:&amp;#xD;&#xD;&#xA;        &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;        &amp;lt;div style=&quot;margin-top: 4px&quot;&amp;gt;&amp;#xD;&#xD;&#xA;          &amp;#xD;&#xD;&#xA;        &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;      &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;      &amp;lt;div style=&quot;padding-top: 12px; padding-right: 12px; padding-bottom: 12px; padding-left: 12px; margin-top: 10px; margin-bottom: 10px; margin-right: 0; margin-left: 0; background-color: #fafafa; background-image: null; background-repeat: repeat; background-attachment: scroll; background-position: null; border-left-color: #4a90e2; border-left-style: solid; border-left-width: 5px&quot;&amp;gt;&amp;#xD;&#xD;&#xA;        &amp;lt;div&amp;gt;&amp;#xD;&#xD;&#xA;          Totals:&amp;#xD;&#xD;&#xA;        &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;        &amp;lt;div style=&quot;margin-top: 4px&quot;&amp;gt;&amp;#xD;&#xD;&#xA;          &amp;#xD;&#xD;&#xA;        &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;      &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;      &amp;lt;div style=&quot;padding-top: 12px; padding-right: 12px; padding-bottom: 12px; padding-left: 12px; margin-top: 10px; margin-bottom: 10px; margin-right: 0; margin-left: 0; background-color: #fafafa; background-image: null; background-repeat: repeat; background-attachment: scroll; background-position: null; border-left-color: #4a90e2; border-left-style: solid; border-left-width: 5px&quot;&amp;gt;&amp;#xD;&#xD;&#xA;        &amp;lt;div&amp;gt;&amp;#xD;&#xD;&#xA;          Scratch Pool Check:&amp;#xD;&#xD;&#xA;        &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;        &amp;lt;div style=&quot;margin-top: 4px&quot;&amp;gt;&amp;#xD;&#xD;&#xA;          &amp;#xD;&#xD;&#xA;        &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;      &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;      &amp;lt;div style=&quot;padding-top: 12px; padding-right: 12px; padding-bottom: 12px; padding-left: 12px; margin-top: 10px; margin-bottom: 10px; margin-right: 0; margin-left: 0; background-color: #fafafa; background-image: null; background-repeat: repeat; background-attachment: scroll; background-position: null; border-left-color: #4a90e2; border-left-style: solid; border-left-width: 5px&quot;&amp;gt;&amp;#xD;&#xD;&#xA;        &amp;lt;div&amp;gt;&amp;#xD;&#xD;&#xA;          Tape Libraries and Status:&amp;#xD;&#xD;&#xA;        &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;      &amp;lt;/div&amp;gt;&amp;#xD;&#xD;&#xA;    &amp;lt;/div&amp;gt;&lt;/body&gt;&lt;html&gt;true&lt;/html&gt;&lt;/email&gt;&lt;/inputs&gt;" />
  </Activity>
  <Activity displayName="JSONToResultSet" interactive="0" originalStyle="" jobMode="0" description="converts a json string to a result set" waitSetting="0" continueOnFailure="0" namespaceUri="commvault.cte.workflow.activities" commented="0" height="34" created="1771548667599" breakpoint="0" uniqueName="JSONToResultSet_1" skipAttempt="0" name="JSONToResultSet" width="131" x="151" y="363" style="label;image=commvault.cte.workflow.activities.JsonToResultSet">
    <inputs val="&lt;inputs&gt;&lt;json class=&quot;java.lang.String&quot; _list_=&quot;false&quot;&gt;xpath:{/workflow/HttpClient_1/output}&lt;/json&gt;&lt;/inputs&gt;" />
    <transition sourceX="216" sourceY="380" activity="ResultSetToHTML_1" targetY="433" targetX="377" originalStyle="" description="" x="0" y="0" transitionIndex="0" style="defaultEdge" commented="0" status="0">
      <condition language="4" script="/*&#xA;The expression should return a boolean. Use the variable name &quot;activity&quot; to refer to the previous activity object. Example:&#xA;activity.exitCode==0;&#xA;*/&#xA;" />
    </transition>
  </Activity>
  <Activity displayName="ResultSetToHTML" interactive="0" originalStyle="" jobMode="0" description="converts a result set to an HTML table" waitSetting="0" continueOnFailure="0" namespaceUri="commvault.cte.workflow.activities" commented="0" height="34" created="1771548712005" breakpoint="0" uniqueName="ResultSetToHTML_1" skipAttempt="0" name="ResultSetToHTML" width="131" x="405" y="290" style="label;image=commvault.cte.workflow.activities.ResultSetToHTML">
    <inputs val="&lt;inputs&gt;&lt;resultSet class=&quot;java.lang.Object&quot; _list_=&quot;false&quot;&gt;xpath:{/workflow/JSONToResultSet_1/resultSet}&lt;/resultSet&gt;&lt;headers class=&quot;java.lang.Boolean&quot; _list_=&quot;false&quot;&gt;false&lt;/headers&gt;&lt;/inputs&gt;" />
    <transition sourceX="470" sourceY="307" activity="Email_1" targetY="276" targetX="667" originalStyle="" description="" points="" x="0" y="0" transitionIndex="0" style="defaultEdge" commented="0" status="0">
      <condition language="4" script="/*&#xA;The expression should return a boolean. Use the variable name &quot;activity&quot; to refer to the previous activity object. Example:&#xA;activity.exitCode==0;&#xA;*/&#xA;" />
    </transition>
  </Activity>
  <formProperties />
  <minCommCellVersion servicePack="0" releaseID="16" />
</Workflow_WorkflowDefinition>
 

Thanks for reading :) 

1 reply

Damian Andre
Vaulter
Forum|alt.badge.img+27

I’m guessing you’d have to parse the JSON and extract the elements you want in the table. I’m guessing your favorite LLM will be able to help with the parsing and formatting into a table.