Dashboards & Visualizations

XML to display in a proper format with tag

DataOrg
Builder

XML to dispaly with proper lining format. below is example with different data

1.<Call><splunk>201</splunk><Time>4547554</Time></Call>
2.<Call><script>201</script><callId>IND00900</callId></Call>
Tags (2)
0 Karma
1 Solution

niketn
Legend

@premranjithj please try the following Simple XML JS extension which should format XML data in the table.

alt text
Following is the Simple XML dashboard code which generates un-formatted XML data rows as per your question:

<dashboard script="table_cell_formatted_xml.js">
  <label>Table with XML Expansion</label>
  <row>
    <panel>
      <table id="table_with_formatted_xml">
        <search>
          <query>| makeresults 
| eval xmlData="<Call><splunk>201</splunk><Time>4547554</Time></Call>;<Call><script>201</script><callId>IND00900</callId></Call>"
| makemv xmlData delim=";"
| mvexpand xmlData
| eval origData=xmlData</query>
          <earliest>-24h@h</earliest>
          <latest>now</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">none</option>
        <option name="percentagesRow">false</option>
        <option name="refresh.display">progressbar</option>
        <option name="rowNumbers">false</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
  </row>
</dashboard>

Following is the required JS file table_cell_formatted_xml.js (PS: I could easily find the JS on Stack Overflow through google: https://stackoverflow.com/questions/376373/pretty-printing-xml-with-javascript):

/* TODO: jink to replace theme_utils with that from core */
require.config({
  paths: {
    theme_utils: '../app/simple_xml_examples/theme_utils'
  }
});

require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/tableview',
    'theme_utils',
    'splunkjs/mvc/simplexml/ready!'
], function(_, $, mvc, TableView, themeUtils) {

     // Row Coloring Example with custom, client-side range interpretation

    var isDarkTheme = themeUtils.getCurrentTheme && themeUtils.getCurrentTheme() === 'dark';

    var CustomRangeRenderer = TableView.BaseCellRenderer.extend({
        canRender: function(cell) {
            // Enable this custom cell renderer for xmlData
            return _(['xmlData']).contains(cell.field);
        },
        render: function($td, cell) {
            // Prettify XML
            $td.text(prettifyXml(cell.value)).addClass('string');
        }
    });

    mvc.Components.get('table_with_formatted_xml').getVisualization(function(tableView) {
        // Add custom cell renderer, the table will re-render automatically.
        tableView.addCellRenderer(new CustomRangeRenderer());
    });

    var prettifyXml = function(sourceXml)
    {
        var xmlDoc = new DOMParser().parseFromString(sourceXml, 'application/xml');
        var xsltDoc = new DOMParser().parseFromString([
            // describes how we want to modify the XML - indent everything
            '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">',
            '  <xsl:strip-space elements="*"/>',
            '  <xsl:template match="para[content-style][not(text())]">', // change to just text() to strip space in text nodes
            '    <xsl:value-of select="normalize-space(.)"/>',
            '  </xsl:template>',
            '  <xsl:template match="node()|@*">',
            '    <xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>',
            '  </xsl:template>',
            '  <xsl:output indent="yes"/>',
            '</xsl:stylesheet>',
        ].join('\n'), 'application/xml');

        var xsltProcessor = new XSLTProcessor();    
        xsltProcessor.importStylesheet(xsltDoc);
        var resultDoc = xsltProcessor.transformToDocument(xmlDoc);
        var resultXml = new XMLSerializer().serializeToString(resultDoc);
        return resultXml;
    };
});
____________________________________________
| makeresults | eval message= "Happy Splunking!!!"

View solution in original post

niketn
Legend

@premranjithj please try the following Simple XML JS extension which should format XML data in the table.

alt text
Following is the Simple XML dashboard code which generates un-formatted XML data rows as per your question:

<dashboard script="table_cell_formatted_xml.js">
  <label>Table with XML Expansion</label>
  <row>
    <panel>
      <table id="table_with_formatted_xml">
        <search>
          <query>| makeresults 
| eval xmlData="<Call><splunk>201</splunk><Time>4547554</Time></Call>;<Call><script>201</script><callId>IND00900</callId></Call>"
| makemv xmlData delim=";"
| mvexpand xmlData
| eval origData=xmlData</query>
          <earliest>-24h@h</earliest>
          <latest>now</latest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">20</option>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">none</option>
        <option name="percentagesRow">false</option>
        <option name="refresh.display">progressbar</option>
        <option name="rowNumbers">false</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
      </table>
    </panel>
  </row>
</dashboard>

Following is the required JS file table_cell_formatted_xml.js (PS: I could easily find the JS on Stack Overflow through google: https://stackoverflow.com/questions/376373/pretty-printing-xml-with-javascript):

/* TODO: jink to replace theme_utils with that from core */
require.config({
  paths: {
    theme_utils: '../app/simple_xml_examples/theme_utils'
  }
});

require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/tableview',
    'theme_utils',
    'splunkjs/mvc/simplexml/ready!'
], function(_, $, mvc, TableView, themeUtils) {

     // Row Coloring Example with custom, client-side range interpretation

    var isDarkTheme = themeUtils.getCurrentTheme && themeUtils.getCurrentTheme() === 'dark';

    var CustomRangeRenderer = TableView.BaseCellRenderer.extend({
        canRender: function(cell) {
            // Enable this custom cell renderer for xmlData
            return _(['xmlData']).contains(cell.field);
        },
        render: function($td, cell) {
            // Prettify XML
            $td.text(prettifyXml(cell.value)).addClass('string');
        }
    });

    mvc.Components.get('table_with_formatted_xml').getVisualization(function(tableView) {
        // Add custom cell renderer, the table will re-render automatically.
        tableView.addCellRenderer(new CustomRangeRenderer());
    });

    var prettifyXml = function(sourceXml)
    {
        var xmlDoc = new DOMParser().parseFromString(sourceXml, 'application/xml');
        var xsltDoc = new DOMParser().parseFromString([
            // describes how we want to modify the XML - indent everything
            '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">',
            '  <xsl:strip-space elements="*"/>',
            '  <xsl:template match="para[content-style][not(text())]">', // change to just text() to strip space in text nodes
            '    <xsl:value-of select="normalize-space(.)"/>',
            '  </xsl:template>',
            '  <xsl:template match="node()|@*">',
            '    <xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>',
            '  </xsl:template>',
            '  <xsl:output indent="yes"/>',
            '</xsl:stylesheet>',
        ].join('\n'), 'application/xml');

        var xsltProcessor = new XSLTProcessor();    
        xsltProcessor.importStylesheet(xsltDoc);
        var resultDoc = xsltProcessor.transformToDocument(xmlDoc);
        var resultXml = new XMLSerializer().serializeToString(resultDoc);
        return resultXml;
    };
});
____________________________________________
| makeresults | eval message= "Happy Splunking!!!"

jimdiconectiv
Path Finder

Hi niketnltay ,  anyone else. 

Clearing my browser (Google Chrome)  catch leaves this working with my different dash board.   The pretty printing is very nice.  I cannot give a large exmple because of sensetive data but here is a small one. 

jimdiconectiv_0-1642007760963.png

Curious why you use the theme_utils from simple_xml_examples ...   Is that necessary ?

Thanks! 

0 Karma

jimdiconectiv
Path Finder

Hi niketnltay , 

Hoping you are back from Holiday and can give me some guidance.   See my just prior comment.  I'm getting error messages and doesn't do Pretty Print.   

Text Error messages are below.   Jim 

=======================================================

Error message in Chrome from answer board code:

VM578:1903 GET http://padv06gf06ski01.npac.ics.iconectiv.com:8000/en-US/vendor/splunk/etc/app/simple_xml_examples/t... net::ERR_ABORTED 404 (Not Found)
req.load @ VM578:1903
load @ VM578:1647
load @ VM578:828
fetch @ VM578:818
check @ VM578:848
enable @ VM578:1151
enable @ VM578:1519
eval @ VM578:1136
eval @ VM578:132
each @ VM578:57
enable @ VM578:1098
init @ VM578:782
eval @ VM578:1424
setTimeout (async)
req.nextTick @ VM578:1763
localRequire @ VM578:1413
requirejs @ VM578:1745
shimmedRequirejsRequire @ dashboard.js:1335
eval @ VM615:15
(anonymous) @ dashboard.js:1335
(anonymous) @ dashboard.js:1308
fire @ dashboard.js:1308
add @ dashboard.js:1308
(anonymous) @ dashboard.js:1308
each @ dashboard.js:1297
(anonymous) @ dashboard.js:1308
Deferred @ dashboard.js:1308
then @ dashboard.js:1308
(anonymous) @ dashboard.js:1335
(anonymous) @ dashboard.js:1308
fire @ dashboard.js:1308
fireWith @ dashboard.js:1308
done @ dashboard.js:1308
(anonymous) @ dashboard.js:1308
load (async)
send @ dashboard.js:1308
ajax @ dashboard.js:1308
_getScript @ dashboard.js:1335
_loadScript @ dashboard.js:1335
_loadExtension @ dashboard.js:1335
loadScriptExtension @ dashboard.js:1335
loadDefaultExtensions @ dashboard.js:1335
applyCustomExtension @ dashboard.js:1335
(anonymous) @ dashboard.js:1308
fire @ dashboard.js:1308
fireWith @ dashboard.js:1308
(anonymous) @ dashboard.js:1308
fire @ dashboard.js:1308
fireWith @ dashboard.js:1308
Deferred.jQuery.each.deferred.<computed> @ dashboard.js:1308
(anonymous) @ dashboard.js:1335
(anonymous) @ dashboard.js:1308
fire @ dashboard.js:1308
fireWith @ dashboard.js:1308
(anonymous) @ dashboard.js:1308
fire @ dashboard.js:1308
fireWith @ dashboard.js:1308
(anonymous) @ dashboard.js:1308
fire @ dashboard.js:1308
fireWith @ dashboard.js:1308
Deferred.jQuery.each.deferred.<computed> @ dashboard.js:1308
(anonymous) @ dashboard.js:1397
(anonymous) @ dashboard.js:1308
fire @ dashboard.js:1308
add @ dashboard.js:1308
(anonymous) @ dashboard.js:1308
each @ dashboard.js:1297
(anonymous) @ dashboard.js:1308
Deferred @ dashboard.js:1308
then @ dashboard.js:1308
createVisualization @ dashboard.js:1397
later @ dashboard.js:1335
setTimeout (async)
(anonymous) @ dashboard.js:1335
render @ dashboard.js:1397
(anonymous) @ dashboard.js:1397
render @ dashboard.js:1397
(anonymous) @ dashboard.js:1397
_addElement @ dashboard.js:1397
addChild @ dashboard.js:1397
addChildToContainer @ dashboard.js:1335
materializeComponent @ dashboard.js:1335
materializeComponentFn @ dashboard.js:1335
(anonymous) @ dashboard.js:1335
_.map._.collect @ dashboard.js:1335
_.<computed> @ dashboard.js:1335
materializeComponents @ dashboard.js:1335
materialize @ dashboard.js:1335
applyDashboardStructure @ dashboard.js:1335
later @ dashboard.js:1335
setTimeout (async)
(anonymous) @ dashboard.js:1335
triggerEvents @ dashboard.js:840
trigger @ dashboard.js:840
set @ dashboard.js:840
parseDashboardXML @ dashboard.js:1335
enter @ dashboard.js:1335
_handleModeChange @ dashboard.js:1335
(anonymous) @ dashboard.js:1308
fire @ dashboard.js:1308
add @ dashboard.js:1308
(anonymous) @ dashboard.js:1308
each @ dashboard.js:1297
(anonymous) @ dashboard.js:1308
Deferred @ dashboard.js:1308
then @ dashboard.js:1308
handleModeChange @ dashboard.js:1335
triggerEvents @ dashboard.js:840
trigger @ dashboard.js:840
set @ dashboard.js:840
(anonymous) @ dashboard.js:1335
(anonymous) @ dashboard.js:1308
fire @ dashboard.js:1308
fireWith @ dashboard.js:1308
(anonymous) @ dashboard.js:1308
fire @ dashboard.js:1308
fireWith @ dashboard.js:1308
(anonymous) @ dashboard.js:1308
fire @ dashboard.js:1308
fireWith @ dashboard.js:1308
Deferred.jQuery.each.deferred.<computed> @ dashboard.js:1308
(anonymous) @ dashboard.js:1335
(anonymous) @ dashboard.js:840
(anonymous) @ dashboard.js:1308
fire @ dashboard.js:1308
fireWith @ dashboard.js:1308
Deferred.jQuery.each.deferred.<computed> @ dashboard.js:1308
(anonymous) @ dashboard.js:840
(anonymous) @ dashboard.js:1308
fire @ dashboard.js:1308
add @ dashboard.js:1308
(anonymous) @ dashboard.js:1308
each @ dashboard.js:1297
(anonymous) @ dashboard.js:1308
Deferred @ dashboard.js:1308
then @ dashboard.js:1308
(anonymous) @ dashboard.js:840
fire @ dashboard.js:1308
fireWith @ dashboard.js:1308
done @ dashboard.js:1308
(anonymous) @ dashboard.js:1308
load (async)
send @ dashboard.js:1308
ajax @ dashboard.js:1308
Backbone.ajax @ dashboard.js:840
Backbone.sync @ dashboard.js:840
sync @ dashboard.js:840
fetch @ dashboard.js:840
fetch @ dashboard.js:840
fetch @ dashboard.js:840
fetch @ dashboard.js:840
(anonymous) @ dashboard.js:1335
fire @ dashboard.js:1308
fireWith @ dashboard.js:1308
Deferred.jQuery.each.deferred.<computed> @ dashboard.js:1308
(anonymous) @ dashboard.js:1335
options.success @ dashboard.js:840
fire @ dashboard.js:1308
fireWith @ dashboard.js:1308
done @ dashboard.js:1308
(anonymous) @ dashboard.js:1308
load (async)
send @ dashboard.js:1308
ajax @ dashboard.js:1308
Backbone.ajax @ dashboard.js:840
Backbone.sync @ dashboard.js:840
sync @ dashboard.js:840
fetch @ dashboard.js:840
fetch @ dashboard.js:840
fetch @ dashboard.js:840
bootstrapAppLocals @ dashboard.js:1335
$whenPageViewDependencies @ dashboard.js:1335
$whenPageViewDependencies @ dashboard.js:1335
(anonymous) @ dashboard.js:1335
(anonymous) @ dashboard.js:1308
fire @ dashboard.js:1308
add @ dashboard.js:1308
(anonymous) @ dashboard.js:1308
each @ dashboard.js:1297
(anonymous) @ dashboard.js:1308
Deferred @ dashboard.js:1308
then @ dashboard.js:1308
page @ dashboard.js:1335
view @ dashboard.js:1335
execute @ dashboard.js:840
(anonymous) @ dashboard.js:840
(anonymous) @ dashboard.js:840
_.some._.any @ dashboard.js:1335
loadUrl @ dashboard.js:840
start @ dashboard.js:840
exports.start_backbone_history @ dashboard.js:1397
(anonymous) @ dashboard.js:263
418 @ dashboard.js:263
__webpack_require__ @ dashboard.js:1
(anonymous) @ dashboard.js:1
(anonymous) @ dashboard.js:1
Show 121 more frames
VM578:166 Uncaught Error: Script error for: theme_utils
http://requirejs.org/docs/errors.html#scripterror
at makeError (eval at module.exports (dashboard.js:685), <anonymous>:166:17)
at HTMLScriptElement.onScriptError (eval at module.exports (dashboard.js:685), <anonymous>:1689:36)

 

0 Karma

jimdiconectiv
Path Finder

niketnltay :

I am trying to adapt the xml pretty print for an application and am having issues.  

One head note, he line from your post:

| eval xmlData="<Call><splunk>201</splunk><Time>4547554</Time></Call>;<Call><script>201</script><callId>IND00900</callId></Call>"

Will not go in for me in that for because the  xml tags in it get taken as Simple XML tags, and I get an error message that <query>  can't have children.  I was able to fix this by changing "<" and ">" to html tags like:

| eval xmlData="&lt;Call&gt;&lt;splunk&gt;201&lt;/splunk&gt;&lt;Time&gt;4547554&lt;/Time&gt;&lt;/Call&gt;:&lt;Call&gt;&lt;script&gt;201&lt;/script&gt;&lt;callId&gt;IND00900&lt;/callId&gt;&lt;/Call&gt;"

This works for getting the XML in, but then I don't get the pretty printing and see errors in google chrome's  developer tools. 

jimdiconectiv_0-1640883240029.png

 

I see very similar java script working for other Simple XML dashboards examples.  using the theme

utils for example:   In the Table Cell Highlighting Example

  1. require.config({
  2. paths: {
  3. theme_utils: '../app/simple_xml_examples/theme_utils'
  4. }
  5. });

    I am wondering  if this is happening because of a change in Splunk version or simple XML examples 

    version.  Both Splunk Versions and Splunk Dashboard Example are version 8.2.0 . 

    I'm getting very similar errors on a simple XML script that pulls log data into xmlData Field . 

     

    _Your help greatly appreciated ! _    Jim Deich

    Text Version of those errors:

    VM578:1903 GET http://padv06gf06ski01.npac.ics.iconectiv.com:8000/en-US/vendor/splunk/etc/app/simple_xml_examples/t...






































































































































































































    http://requirejs.org/docs/errors.html#scripterror
    at makeError (eval at module.exports (dashboard.js:...

     

     

     

     

jimdiconectiv_2-1640882973195.png

Tags (2)
0 Karma

DataOrg
Builder

@niketnilay thanks 🙂 . worked like a charm

0 Karma

niketn
Legend

@premranjithj please add more details to what do you mean by proper line formatting? Do you have sample output? Which viz are you trying to show the above XML?

Does any of options in one of my older answer for JSON work for you with XML?

https://answers.splunk.com/answers/587044/can-i-custom-code-a-splunk-table-to-include-json-i-1.html

Please check out and confirm. If not, please add more details on requirements for the community to assist you better.

____________________________________________
| makeresults | eval message= "Happy Splunking!!!"
0 Karma

DataOrg
Builder

@niketnilay
example should be like this .sometime the XML will have more tags

<Call>
    <splunk>201</splunk>
    <Time>4547554</Time>
</Call>
0 Karma
Get Updates on the Splunk Community!

Index This | I am a number, but when you add ‘G’ to me, I go away. What number am I?

March 2024 Edition Hayyy Splunk Education Enthusiasts and the Eternally Curious!  We’re back with another ...

What’s New in Splunk App for PCI Compliance 5.3.1?

The Splunk App for PCI Compliance allows customers to extend the power of their existing Splunk solution with ...

Extending Observability Content to Splunk Cloud

Register to join us !   In this Extending Observability Content to Splunk Cloud Tech Talk, you'll see how to ...