Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Rendering XML in HTML and formatting text strings

Posted on 2009-05-14
7
Medium Priority
?
508 Views
Last Modified: 2012-05-07
OK...So I have an XML document that I parse and represent in simple HTML format via AJAX.  I have the structure already in place however I am having difficulty showing some extra options.  

What I have for the current method of rendering is in the code block below.  It works great however I would like to add a few other options such as:

1)  Have the "ReportHostRow.appendChild(document.createElement('TD')).innerHTML = 'Nessus #';" row auto increment to look like "Nessus-1", "Nessus-2", etc.  I tried a for loop and it worked but only showed the selected rows with a severity level of "2" or "3".  I just want it to list 1, 2, 3, etc before it is filtered according to the severity level.  Is that possible?  I had it working within the loop but it would list such as "12, 24, 33, etc" instead of "1,2,3,4".

2)  I would like to combine the 'pluginName' and 'data' elements of the XML into one cell for each row under the ReportHostRow. So that it would look so the titel (in XML document its 'pluginName') is bold and a space is below it for the Detailed Data (in XML document its 'data')

      <b>Windows Remote Desktop was found</b></br>      
       It may be possible to get access to the remote host. \n\nDescription :\n\nThe remote version of Remote Desktop  
       Protocol Server (Terminal\nService) is vulnerable to a man in the middle attack.


I got help with the code in the first place I am not really sure how to implement it.  Any help would be greatly appreciated.  Also, please try not to make too many changes that are a drastic departure from what I already have and if you do can you describe it as much detail as possible.  I sincerely appreciate it.


<NessusClientData>
<Report>
<ReportName>09/03/18 08:14:55 AM - Default scan policy</ReportName>
<ReportHost>
<HostName>192.168.1.101</HostName>
<startTime>Wed Mar 18 08:14:55 2009</startTime>
<stopTime>Wed Mar 18 10:23:47 2009</stopTime>
<netbios_name>Server1</netbios_name>
<mac_addr>(unknown)</mac_addr>
<dns_name>SERVER1.</dns_name>
<os_name>Microsoft Windows Server 2003, Enterprise Edition (English)</os_name>
<num_ports>16</num_ports>
<num_lo>57</num_lo>
<num_med>1</num_med>
<num_hi>0</num_hi>

<ReportItem>
<port>general/tcp</port>
<severity>1</severity>
<pluginID>10180</pluginID>
<pluginName>Ping the remote host</pluginName>
<data>The remote host is up\n</data>
</ReportItem>

<ReportItem>
<port>ms-wbt-server (3389/tcp)</port>
<severity>2</severity>
<pluginID>18405</pluginID>
<pluginName>Microsoft Windows Remote Desktop Protocol Server Private Key Disclosure Vulnerability</pluginName>
<data>Synopsis :\n\nIt may be possible to get access to the remote host. \n\nDescription :\n\nThe remote version of Remote Desktop Protocol Server (Terminal\nService) is vulnerable to a man

in the middle attack. \n\nAn attacker may exploit this flaw to decrypt communications between\nclient and server and obtain sensitive information (passwords, ...). \n\nSolution :\n\nForce the use

of SSL as a transport layer for this service.\n\nSee also :\n\nhttp://www.oxid.it/downloads/rdp-gbu.pdf\nhttp://technet.microsoft.com/en-us/library/cc782610.aspx\n\nRisk factor :\n\nMedium /

CVSS Base Score : 5.1\n(CVSS2#AV:N/AC:H/Au:N/C:P/I:P/A:P)\nCVE : CVE-2005-1794, CVE-2005-1794\nBID : 13818, 13818\n</data>
</ReportItem>

<ReportItem>
<port>ms-wbt-server (3389/tcp)</port>
<severity>3</severity>
<pluginID>30218</pluginID>
<pluginName>Terminal Services Encryption Level is not FIPS-140 compliant</pluginName>
<data>\nSynopsis :\n\nThe remote host is

not FIPS-140 compliant.\n\nDescription :\n\nThe remote host is running Terminal Services Server. The encryption settings\nused by the remote service is not FIPS-140 compliant.\n\nSolution

:\n\nChange RDP encryption level to :\n 4. FIPS Compliant\n\nRisk factor :\n\nLow / CVSS Base Score : 2.6 \n(CVSS2#AV:N/AC:H/Au:N/C:P/I:N/A:N)\n\nPlugin output :\nThe terminal services

encryption level is set to:\n2. Medium (Client Compatbile)\n</data>
</ReportItem>
</ReportHost>
<ReportHost>
<HostName>192.168.1.103</HostName>
<startTime>Wed Mar 18 09:58:08 2009</startTime>
<stopTime></stopTime>
<netbios_name>Server2</netbios_name>
<mac_addr>(unknown)</mac_addr>
<dns_name>(unknown)</dns_name>
<os_name>(unknown)</os_name>
<num_ports>14</num_ports>
<num_lo>18</num_lo>
<num_med>1</num_med>
<num_hi>0</num_hi>
<ReportItem>
<port>general/tcp</port>
<severity>3</severity>
<pluginID>10180</pluginID>
<pluginName>Ping the remote host</pluginName>
<data>The remote host is up\n</data>
</ReportItem>
<ReportItem>
<port>netbios-ssn (139/tcp)</port>
<severity>1</severity>
<pluginID>11011</pluginID>
<pluginName>SMB Detection</pluginName>
<data>\nSynopsis :\n\nA file / print sharing service is listening on the remote host. \n\nDescription :\n\nThe remote service understands the CIFS (Common Internet File System)\nor Server

Message Block (SMB) protocol, used to provide shared access\nto files, printers, etc between nodes on a network. \n\nRisk factor : \n\nNone\n\nPlugin output :\n\nAn SMB server is running on

this port.\n\n</data>
</ReportItem>
</ReportHost>
</Report>
</NessusClientData>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>Untitled Document</title>
	<script type="text/javascript">
	    function _xml_loadDocument(path) {
	    	var xmlDoc;
			try { // IE
				xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
			}
			catch (ex) {
				try { // Gecko
					xmlDoc = document.implementation.createDocument("","",null);
				}
				catch (ex) {
					alert('Your browser cannot handle this scrHostNamet');
				}
			}
			xmlDoc.async = false;
			xmlDoc.load(path);
			return xmlDoc;
		}
 
		//make the table
 
		function renderTableBody(parentElement) {
			var tableEl = parentElement.appendChild(document.createElement('TABLE'));
			tableEl.cellPadding = '5';
			tableEl.style.width = '300px';
			tableEl.style.textAlign = "left";
 
			var tableBody = tableEl.appendChild(document.createElement('TBODY'));
 
			// Render header cells.
			var headerRow = tableBody.appendChild(document.createElement('TR'));
			headerRow.appendChild(document.createElement('TD')).innerHTML = 'Finding Number';
			headerRow.appendChild(document.createElement('TD')).innerHTML = 'NIST 800-53 / DHS Control Severity';
			headerRow.appendChild(document.createElement('TD')).innerHTML = 'Machine Name';
			headerRow.appendChild(document.createElement('TD')).innerHTML = 'IP Address';		
			headerRow.appendChild(document.createElement('TD')).innerHTML = 'Severity';			
			headerRow.appendChild(document.createElement('TD')).innerHTML = 'Finding (pluginname + Data)';
			headerRow.appendChild(document.createElement('TD')).innerHTML = 'Details';
 
			return tableBody;
		}
		
		function renderColumn(ReportHostRow, ReportHost, name) {
			var lookupNode = ReportHost.getElementsByTagName(name)[0];
			if (lookupNode && lookupNode.childNodes[0]) {
				var nodeValue = lookupNode.childNodes[0].nodeValue;
				ReportHostRow.appendChild(document.createElement('TD')).innerHTML = nodeValue;
			}
		}
		
	
	
	function renderReportHost(tableBody, ReportHost) {
		// Get all the 'ReportItem' elements within the ReportHost
		var xmlReportItem = ReportHost.getElementsByTagName("ReportItem");
		
		// Go through each one
		var heading = false;
		for (var i = 0; i < xmlReportItem.length; ++i) {
			 
	   	// Determine the severity level of this ReportItem item   
	   	var severitylevel = xmlReportItem[i].getElementsByTagName('severity')[0].childNodes[0].nodeValue;
	  	
		 // We only care about Medium or High
	  	 if ((severitylevel == '2') || (severitylevel == '3')) {
		var ReportHostRow = tableBody.appendChild(document.createElement('TR'));
			
		// If we haven't shown the ReportHost details already, show them
		if (heading==false) {
			heading = true;
			ReportHostRow.appendChild(document.createElement('TD')).innerHTML = 'Nessus #';	
			ReportHostRow.appendChild(document.createElement('TD')).innerHTML = 'SI-2';
			//DNS Name
			renderColumn(ReportHostRow, ReportHost, 'netbios_name');
			//IP Address
			renderColumn(ReportHostRow, ReportHost, 'HostName');
 
			
		} else {
		// Otherwise, show blank fields for ReportHost details as they are shown above this row
					ReportHostRow.appendChild(document.createElement('TD')).innerHTML = ' ';
					ReportHostRow.appendChild(document.createElement('TD')).innerHTML = ' ';
					ReportHostRow.appendChild(document.createElement('TD')).innerHTML = ' ';
					ReportHostRow.appendChild(document.createElement('TD')).innerHTML = ' ';
					
				}
				
			// Now show the ReportItem results...
			renderColumn(ReportHostRow, xmlReportItem[i], 'severity');
			renderColumn(ReportHostRow, xmlReportItem[i], 'pluginName');
			renderColumn(ReportHostRow, xmlReportItem[i], 'data');
			
			
		}
	}
}
 
		function renderXML(path, parentElement) {
			try {
				var xmlDoc = _xml_loadDocument(path);
				var tableBody = renderTableBody(parentElement || document.body);
 				var xmlReportHosts = xmlDoc.getElementsByTagName("ReportHost");
				for (var i = 0; i < xmlReportHosts.length; ++i) {
					renderReportHost(tableBody, xmlReportHosts[i]);
				}
			}
			catch (ex) {
				alert('Your browser cannot handle this scrHostNamet');
			}
		}
	</script>
</head>
<body onload="renderXML('NessusSmall.xml');">
	
</body>
</html>

Open in new window

0
Comment
Question by:shark1998
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
7 Comments
 

Author Comment

by:shark1998
ID: 24385123
Oh...I almost forgot.  As you can see the 'data' nodes show a  '\n' break however in the HTML document that renders the XML it still shows it as simple text '\n'  is there a way to have the break automatically rendered?  I thought there was a way to display it but am too noob to implement it.  I.E.:

<data>\nSynopsis :\n\nA file / print sharing service is listening on the remote host. \n\nDescription :\n\nThe remote service understands the CIFS (Common Internet File System)\nor Server
Message Block (SMB) protocol, used to provide shared access\nto files, printers, etc between nodes on a network. \n\nRisk factor : \n\nNone\n\nPlugin output :\n\nAn SMB server is running on this port.\n\n</data>
0
 
LVL 49

Accepted Solution

by:
Roonaan earned 1000 total points
ID: 24392613
1) I think you can just get the amount of already inserted table rows:
Change from
ReportHostRow.appendChild(document.createElement('TD')).innerHTML = 'Nessus #';
To
ReportHostRow.appendChild(document.createElement('TD')).innerHTML = 'Nessus ' + (tableBody.rows.length+1);

2)  You could upgrade renderColumn to allow an additional 'title' field to be mentioned:
The call to renderColumn would change to:
   renderColumn(ReportHostRow, xmlReportItem[i], 'data','pluginName');

While renderColumn itself would change to
function renderColumn(ReportHostRow, ReportHost, name, titleFieldName) {
                        var lookupNode = ReportHost.getElementsByTagName(name)[0];
                        if (lookupNode && lookupNode.childNodes[0]) {
                                var nodeValue = lookupNode.childNodes[0].nodeValue;

                                // see if a bold titlefield is requested, do a lookup and prepend it to nodevalue
                                if(typeof titleFieldName != 'undefined') {
                                    var titleNode = ReportHost.getElementsByTagName(titleFieldName)[0];
                                    if(titleNode && titleNode.childNodes[0]) {
                                          nodeValue = "<b>"+ titleNodes.childNodes[0].nodeValue + "</b><br />" + nodeValue;
                                    }
                                }

                                // Get newlines to work
                                nodeValue = nodeValue.replace(/\\n/g, "<br />");

                                // Add row to table
                                ReportHostRow.appendChild(document.createElement('TD')).innerHTML = nodeValue;
                        }
                }


For the newline issue I added:
nodeValue = nodeValue.replace(/\\n/g, "<br />");

Kind regards

Arnoud
0
 

Author Comment

by:shark1998
ID: 24396707
Roonaan:

You definately helping me make progress.....One questions regarding
renderColumn(ReportHostRow, xmlReportItem[i], 'data','pluginName');

When you mentioned an additional 'title' field were you refering to "pluginName" or something else?  I assumed you would want me to rename the "titleFieldName" to "pluginName" for that is the extra data that I wanted.

Am I asking this clearly or am I confusing everybody?





2)  You could upgrade renderColumn to allow an additional 'title' field to be mentioned:
The call to renderColumn would change to:
   renderColumn(ReportHostRow, xmlReportItem[i], 'data','pluginName');

While renderColumn itself would change to
function renderColumn(ReportHostRow, ReportHost, name, titleFieldName) {
                        var lookupNode = ReportHost.getElementsByTagName(name)[0];
                        if (lookupNode && lookupNode.childNodes[0]) {
                                var nodeValue = lookupNode.childNodes[0].nodeValue;

                                // see if a bold titlefield is requested, do a lookup and prepend it to nodevalue
                                if(typeof titleFieldName != 'undefined') {
                                    var titleNode = ReportHost.getElementsByTagName(titleFieldName)[0];
                                    if(titleNode && titleNode.childNodes[0]) {
                                          nodeValue = "<b>"+ titleNodes.childNodes[0].nodeValue + "</b><br />" + nodeValue;
                                    }
                                }

                                // Get newlines to work
                                nodeValue = nodeValue.replace(/\\n/g, "<br />");

                                // Add row to table
                                ReportHostRow.appendChild(document.createElement('TD')).innerHTML = nodeValue;
                        }
                }
0
Learn by Doing. Anytime. Anywhere.

Do you like to learn by doing?
Our labs and exercises give you the chance to do just that: Learn by performing actions on real environments.

Hands-on, scenario-based labs give you experience on real environments provided by us so you don't have to worry about breaking anything.

 
LVL 49

Expert Comment

by:Roonaan
ID: 24396877
titleFieldName is the variable inside the renderColumn function. 'pluginName' is the value you can use, but you might as well use something else per column


renderColumn(ReportHostRow, xmlReportItem[i], 'data','pluginName');
renderColumn(ReportHostRow, xmlReportItem[i], 'data','some other field');
0
 

Author Comment

by:shark1998
ID: 24398275
I'm sorry Roonaan,  if I ad "pluginName' as such...it still does not combine the data in both "data" and "pluginName"  The script curently looks like this in an HTML ( The | is just the cell border for example):

Nessus -4      |      SI-2 Server     |      etc     |     etc    | etc    |   Ping the remote host   |   The remote host is up

I would like it to look like this:

Nessus -4      |         SI-2 Server     |    etc   |    etc    | etc   |   Ping the remote host    
                                                                                               The remote host is up


Where the "Ping the remote host" from "pluginName" is combined with "The remote host is up" from "data".
0
 

Author Comment

by:shark1998
ID: 24431533
Do you have a solution for my last question?
0

Featured Post

Build and deliver software with DevOps

A digital transformation requires faster time to market, shorter software development lifecycles, and the ability to adapt rapidly to changing customer demands. DevOps provides the solution.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A while back, I ran into a situation where I was trying to use the calculated columns feature in SharePoint 2013 to do some simple math using values in two lists. Between certain data types not being accessible, and also with trying to make a one to…
Originally, this post was published on Monitis Blog, you can check it here . In business circles, we sometimes hear that today is the “age of the customer.” And so it is. Thanks to the enormous advances over the past few years in consumer techno…
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

721 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question