I have an xml file which i want to convert to an unordered list using jquery.
so far I managed to get the list working, except for the third level of the xml. Currently my code writes all child items of 'Navigation_sub_3'.
What I'm trying to figure out is how to write only the child nodes that are in level_2, so the output would be
Strategy
Views
IBM
etc.
UML
Development
Architecure
etc
Platform
Model
BPEL
OSLO
etc
Service
Google
Live
etc.
Below is my html/jquery file and the xml. Can anyone help me out how to display the 3rd level?
Cheers
Chris
test.html
<!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 id="Head1" runat="server">
<title></title>
<script src="js/jquery-1.2.6.js" type="text/javascript"></script>
<script type="text/javascript">
function XmlOnLoad(xmlData, strStatus)
{
var jData = $(xmlData);
var jccNav = jData.find("Navigation");
var jSections = jccNav.children();
var jList = $("#Navi");
jSections.each(function(intSectionIndex)
{
var jSection = $(this);
var jTerm = $("<li></li>");
var jDef2 = $("<ul></ul>");
var jLevel2 = $("<b></b>");
var jLevel3 = $("<b></b>");
jSection.children().children().each(function(intPartIndex)
{
var jPart3 = $(this);
var jText3 = $("<li></li>");
// Set the li text.
jText3.html("<a>" + jPart3.attr("tooltip") + "3.level</a>");
// Append to list.
jLevel3.append(jText3);
});
jSection.children().each(function(intPartIndex)
{
var jPart2 = $(this);
var jText2 = $("<li></li>");
// Set the li text.
jText2.html("<a>" + jPart2.attr("tooltip") + " 2.level </a><ul>" + jLevel3.html());
// Append to list.
jLevel2.append(jText2);
});
jTerm.html("<a>"
+ $(this).attr("tooltip")
+ "1.ebene</a>"
+ "<ul>"
+ jLevel2.html()
);
jList.append(jTerm);
$("#homer").html(jList.html());
});
};
$(document).ready(function()
{
$.get("content.xml", {}, XmlOnLoad);
});
</script>
</head>
<body>
<div id="homer"></div>
</body>
</html>
Content.xml
<?xml version="1.0" encoding="utf-8"?>
<Navigation>
<Navigation_sub_1 tooltip="Strategy">
<!--1 Button-->
<level_2 name="Nav1" number="5" tooltip="Views">
<level_3 name="Nav1_5" number="15" tooltip="IBM" />
<level_3 name="Nav1_5" number="13" tooltip="Mainframe" />
<level_3 name="Nav1_5" number="7" tooltip="Novell" />
<level_3 name="Nav1_5" number="6" tooltip="Open- Source"/>
<level_3 name="Nav1_5" number="1" tooltip="Oracle" />
<level_3 name="Nav1_5" number="9" tooltip="SAP" />
<level_3 name="Nav1_5" number="8" tooltip="Sun" />
</level_2>
</Navigation_sub_1>
<!--2 Button-->
<Navigation_sub_2 tooltip="UML">
<level_2 name="Nav2" number="5" tooltip="Development">
<level_3 name="Nav2_5" number="10" tooltip="Architecture"/>
<level_3 name="Nav2_5" number="6" tooltip="Patterns" />
<level_3 name="Nav2_5" number="1" tooltip="SOA" />
</level_2>
</Navigation_sub_2 >
<!--3 Button-->
<Navigation_sub_3 tooltip="Platform">
<level_2 name="Nav3" number="1" tooltip="Model">
<level_3 name="Nav3_1" number="15" tooltip="BPEL" />
<level_3 name="Nav3_1" number="9" tooltip="BPMN" />
<level_3 name="Nav3_1" number="7" tooltip="DSL" />
<level_3 name="Nav3_1" number="10" tooltip="Oslo" />
<level_3 name="Nav3_1" number="1" tooltip="UML" />
</level_2>
<level_2 name="Nav3" number="7" tooltip="Service" >
<level_3 name="Nav3_7" number="3" tooltip="Azure Services" />
<level_3 name="Nav3_7" number="11" tooltip="ISB" />
<level_3 name="Nav3_7" number="6" tooltip="Live" />
<level_3 name="Nav3_7" number="8" tooltip="Live Mesh" />
<level_3 name="Nav3_7" number="13" tooltip="REST" />
<level_3 name="Nav3_7" number="9" tooltip="Web- services" />
<level_3 name="Nav3_7" number="1" tooltip="Windows Azure" />
</level_2>
</Navigation_sub_3>
</Navigation>
Have you tried to use some recursion? You could write a javascript function called writeSection. This function would write each node in a section and then if a node has children, it would call itself to write those children.
Related
My issue is when I make a call for a 'childNode' in my XML file. Everything works fine if there is information between the tags. If it is 'null' or empty, then my script errors out and doesn't continue processing. How do I get my script to ignore the 'null' childNode and continue running? I'm wanting to ignore the null reference and continue processing my XML file because some fields will be empty.
I'm getting this error:
Unable to get property 'nodeValue' of undefined or null reference.
--- HTML/HTA File - Works in IE 11 or as an .hta file
<!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" /> -->
<!-- <meta http-equiv="X-UA-Compatible" content="IE=10"> -->
<meta charset="utf-8">
<title>:: Races ::</title>
<HTA:APPLICATION
SCROLL="no"
SINGLEINSTANCE="yes"
SYSMENU="yes"
BORDER="dialog"
ICON="ms-icon-144x144.png"
>
<!-- *** SETS HTA's WINDOW SIZE *** -->
<SCRIPT LANGUAGE="VBScript">
Sub Window_onLoad
window.resizeTo 1600,700
End Sub
</SCRIPT>
<!-- END SETS HTA's WINDOW SIZE *** -->
</head>
<body onload="LoadXML();">
<!-- *** XML - WRITE TO LOCAL FILE SCRIPT - XML *** -->
<script type ="text/javascript">
function WriteToFileXML()
{
try
{
var WshNetwork = new ActiveXObject("Microsoft.XMLDOM");
var userName = WshNetwork.UserName;
var fso, s;
fso = new ActiveXObject("Scripting.FileSystemObject");
if(fso.FileExists("M:/Races/test.xml")){
s = fso.OpenTextFile("M:/Races/test.xml", 2, true);
} else {
s = fso.CreateTextFile("M:/Races/test.xml", true);
}
var one_seq=document.getElementById("OneSeqCheckbox").checked;
var one_race_field=document.getElementById("OneRaceField").value;
var one_county_selected=document.getElementById("OneCountySelected").value;
var two_seq=document.getElementById("TwoSeqCheckbox").checked;
var two_race_field=document.getElementById("TwoRaceField").value;
var two_county_selected=document.getElementById("TwoCountySelected").value;
var three_seq=document.getElementById("ThreeSeqCheckbox").checked;
var three_race_field=document.getElementById("ThreeRaceField").value;
var three_county_selected=document.getElementById("ThreeCountySelected").value;
s.writeline("\<\?xml version\=\"1\.0\" encoding\=\"UTF\-8\" standalone\=\"yes\"\?\>");
s.writeline("\<Races\_data xmlns\:xsi\=\"http\:\/\/www\.w3\.org\/2001\/XMLSchema\-instance\"\>");
if (one_seq==false)
{
s.writeline("");
}
else
{
s.writeline(" \<record\>");
s.writeline(" \<Race\_Name\>" + one_race_field + "\<\/Race\_Name\>");
s.writeline(" \<County\_Selected\>" + one_county_selected + "\<\/County\_Selected\>");
s.writeline(" \<\/record\>");
}
if (two_seq==false)
{
s.writeline("");
}
else
{
s.writeline(" \<record\>");
s.writeline(" \<Race\_Name\>" + two_race_field + "\<\/Race\_Name\>");
s.writeline(" \<County\_Selected\>" + two_county_selected + "\<\/County\_Selected\>");
s.writeline(" \<\/record\>");
}
if (three_seq==false)
{
s.writeline("");
}
else
{
s.writeline(" \<record\>");
s.writeline(" \<Race\_Name\>" + three_race_field + "\<\/Race\_Name\>");
s.writeline(" \<County\_Selected\>" + three_county_selected + "\<\/County\_Selected\>");
s.writeline(" \<\/record\>");
}
s.writeline("\<\/Races\_data\>");
s.Close();
}
catch(err)
{
var strErr = 'Error:';
strErr += '\nNumber:' + err.number;
strErr += '\nDescription:' + err.description;
document.write(strErr);
}
}
</script>
<!-- *** XML - END WRITE TO LOCAL FILE SCRIPT - XML *** -->
<h1>Races</h1>
<form id="myForm" onkeypress="return (event.keyCode !== 38);" onselectstart="return false" onpaste="return false;" onCopy="return false" onCut="return false" onDrag="return false" onDrop="return false" autocomplete=off>
<div style="width:1300px;height:485px;overflow:auto;">
<input name="OneRaceField" type="text" id="OneRaceField" size="30" /></td>
<select name="OneCountySelected" id="OneCountySelected">
<option value="" selected="selected"></option>
<option value="Mars County">Mars County</option>
<option value="Jupiter County">Jupiter County</option>
</select>
<input name="TwoRaceField" type="text" id="TwoRaceField" size="30" /></td>
<select name="TwoCountySelected" id="TwoCountySelected">
<option value="" selected="selected"></option>
<option value="Mars County">Mars County</option>
<option value="Jupiter County">Jupiter County</option>
</select>
<input name="ThreeRaceField" type="text" id="ThreeRaceField" size="30" /></td>
<select name="ThreeCountySelected" id="ThreeCountySelected">
<option value="" selected="selected"></option>
<option value="Mars County">Mars County</option>
<option value="Jupiter County">Jupiter County</option>
</select>
</div>
<br />
<br />
<br />
<div style="width: 150px; height: 200px; position:absolute; left: 1350px; top: 135px;">
<input style="width: 150px; height: 200px;" name="write_to_file" type="button" id="write_to_file" onClick="Validate(); WriteToFileXML(); RunExe();" value="Save Changes" />
<img src="please_wait.jpg" id="loading_image" name="loading_image" style="display:none" />
</div>
<div style="width: 150px; height: 200px; position:absolute; left: 1350px; top: 367px;">
<input style="width: 150px; height: 200px;" name="Reset_Form" type="button" id="Reset_Form" onClick="resetForm(); WriteToFileXML(); RunExe();" value="Reset Form" />
</div>
<!-- <div style="width: 150px; height: 200px; position:absolute; left: 693px; top: 367px;">
<input style="width: 150px; height: 200px;" name="upload_to_website" type="button" id="upload_to_website" onClick="RunExe();" value="Upload to Website" />
</div> -->
</form>
<script type="text/javascript">
function LoadXML()
{
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
var fso = new ActiveXObject("Scripting.FileSystemObject");
//if(fso.fileExists("M:/Races/test.xml"))
{
xmlDoc.load("M:/Races/test.xml");
document.getElementById("OneRaceField").innerText =
xmlDoc.getElementsByTagName("Race_Name")[0].childNodes[0].nodeValue;
document.getElementById("OneCountySelected").value =
document.getElementById("TwoRaceField").innerText =
xmlDoc.getElementsByTagName("Race_Name")[1].childNodes[0].nodeValue;
document.getElementById("TwoCountySelected").value =
document.getElementById("ThreeRaceField").innerText =
xmlDoc.getElementsByTagName("Race_Name")[2].childNodes[0].nodeValue;
document.getElementById("ThreeCountySelected").value =
xmlDoc.getElementsByTagName("County_Selected")[2].childNodes[0].nodeValue;
}
}
</script>
</body>
</html>
--- test.xml - File Works fine
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Races_data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<record>
<Race_Name>Mayor 1</Race_Name>
<County_Selected>Mars County</County_Selected>
</record>
<record>
<Race_Name>Mayor 2</Race_Name>
<County_Selected>Jupiter County</County_Selected>
</record>
<record>
<Race_Name>Mayor 3</Race_Name>
<County_Selected>Mars County</County_Selected>
</record>
</Races_data>
--- test.xml - Script stops/errors out because of missing information here:
<Race_Name></Race_Name>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Races_data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<record>
<Race_Name>Mayor 1</Race_Name>
<County_Selected>Mars County</County_Selected>
</record>
<record>
<Race_Name></Race_Name>
<County_Selected>Jupiter County</County_Selected>
</record>
<record>
<Race_Name>Mayor 3</Race_Name>
<County_Selected>Mars County</County_Selected>
</record>
</Races_data>
For ajax you have to do something like that :
var my_url = 'M:/Races/test.xml';
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (4 === this.readyState) { /* DONE */
if (200 === this.status) { /* LOADING */
fctCallBack(this);
}
else {
console.warn("Error %d loading %s !", this.status, my_url);
}
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
function fctCallBack(xml) {
var xmlDoc = xml.responseXML;
xmlDoc.querySelectorAll('record').forEach(
function (record) {
console.log( 'Race_Name =' , record.querySelector('Race_Name').value )
console.log( 'County_Selected =' , record.querySelector('County_Selected').value )
}
)
}
I don't know if I have understood the right context of 'storage', but according to some tutorials I used the following Javascript code, to enable a page to locally store (no session) submitted data, but when I close the page and reopen the page, the content do not appear.
script.js
function initiate()
{
var saveButton = document.getElementById('save');
var retrieveButton = document.getElementById('retrieve');
var deleteButton = document.getElementById('delete');
var reviewButton = document.getElementById('review');
saveButton.addEventListener('click', saveItem);
retrieveButton.addEventListener('click', retrieveItem);
deleteButton.addEventListener('click', deleteItem);
reviewButton.addEventListener('click', reviewAll);
}
function saveItem()
{
var key = document.getElementById('key').value;
var value = document.getElementById('value').value;
localStorage[key] = value;
}
function retrieveItem()
{
var data = document.getElementById('data');
var key = document.getElementById('key').value;
var value = localStorage[key];
data.innerHTML = '<div>' + key + ': ' + value + '</div>';
}
function deleteItem()
{
if (confirm('Delete?'))
{
var key = document.getElementById('key').value;
localStorage.removeItem(key);
data.innerHTML = '<div>Deleted.</div>';
}
}
function reviewAll()
{
for(var i = 0; i < localStorage.length; i++)
{
var key = localStorage.key(i);
var value = localStorage[key];
data.innerHTML += '<div>' + key + ': ' + value + '<br></div>';
}
}
addEventListener("load", initiate);
index.html
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="mystyles.css" />
<script src="script.js"></script>
<title>Demo HTML5</title>
</head>
<body>
<section id="formSection">
<form name="dataForm">
<label for="key">Key: </label><br />
<input type="text" id="key" name="key" /> <br />
<label for="value">Value: </label><br />
<textarea name="value" id="value"></textarea><br />
<input type="button" id="save" value="Save" />
<input type="button" id="retrieve" value="Retrieve" />
<input type="button" id="delete" value="Delete" />
<input type="button" id="review" value="Review" />
</form>
</section>
<section id="data">
No data
</section>
</body>
</html>
If you are using the browser in privacy mode, it will clear all localStorage data when you close it.
When the clone button is clicked, size and length fields should be cloned and placed below. Crucial point is, I should be able to see these cloned mark-up code when I check the browser source code because I'll submit all fields.
HTML
<style>
div { display:inline-block; }
.needles, .yarns, .options { border:1px solid #14A; padding:10px; }
</style>
<div class='needles'>
<p>NEEDLES</p>
<div class='options'>
<div class='label'>Size</div>
<div class='field'>
<input id='size-0' name='size-0' value='Size' />
</div>
</div>
<br />
<div class='options'>
<div class='label'>Length</div>
<div class='field'>
<input id='length-0' name='length-0' value='Length' />
</div>
</div>
<br /><br />
<button>Clone</button>
</div>
<br />
<div class='yarns'>
<p>YARNS</p>
<div class='options'>
<div class='label'>Size</div>
<div class='field'>
<input id='size-0' name='size-0' value='Size' />
</div>
</div>
<br />
<div class='options'>
<div class='label'>Length</div>
<div class='field'>
<input id='length-0' name='length-0' value='Length' />
</div>
</div>
<br /><br />
<button>Clone</button>
</div>
I did something like this but I think it is a mess to be honest.
$("button").click(function(event) {
event.preventDefault();
var $parent = $(this).closest('div');
var $length = $parent.prev();
var $size = $length.prev();
var size = $size.clone(false).wrap('<p>').parent().html();
var length = $length.clone(false).wrap('<p>').parent().html();
var spanId = $(size).children('span').attr('id');
var idArray = spanId.split("__");
var currentIdentifierNo = idArray[idArray.length-2];
var newIdentifierNo = parseInt(currentIdentifierNo)+1;
var currentIdentifier = '__' + currentIdentifierNo + '__';
var newIdentifier = '__' + newIdentifierNo + '__';
var re = new RegExp(currentIdentifier, 'g');
size = size.replace(re, newIdentifier);
length = length.replace(re, newIdentifier);
var html = size + length;
$(this).before(html);
});
You have to change the name attribute for this to work:
length.find('input').attr('name', 'length-1');
size.find('input').attr('name', 'size-1');
If you send the same key / value pairs in the form, the server doesn't know which is which.
I am using YQL to pull in a remote XML feed, I have this working in all other areas, but cannot get it to parse the data and format into a table. Here is my fiddle. The xml looks like this:
<string xmlns="http://tempuri.org/">
<?xml version="1.0" encoding="utf-16"?>
<BTCE>
<TickerList />
<Ticker>
<Average Value="" />
<BuyPrice Value="443.95" />
<Currency Value="USD" />
<High Value="456.96" />
<Low Value="424.00" />
<SellPrice Value="444.27" />
<Volume Value="18754.79784877" />
<LastPrice Value="443.95" />
<Time Value="04/28/2014 15:56:54" />
</Ticker>
<Ticker>
<Average Value="" />
<BuyPrice Value="444.32" />
<Currency Value="USD" />
<High Value="456.96" />
<Low Value="424.00" />
<SellPrice Value="444.70" />
<Volume Value="18762.65028563" />
<LastPrice Value="443.96" />
<Time Value="04/28/2014 15:57:57" />
</Ticker>
<Ticker>
<Average Value="" />
<BuyPrice Value="444.32" />
<Currency Value="USD" />
<High Value="456.96" />
<Low Value="424.00" />
<SellPrice Value="445.00" />
<Volume Value="18758.16227820" />
<LastPrice Value="444.32" />
<Time Value="04/28/2014 15:58:08" />
</Ticker>
</BTCE>
I have the following HTML mark up:
<table class="fluid" id="BuyOrders">
<tr>
<th>Price per/ BTC</th>
<th>Quantity, ฿</th>
<th>Total, $</th>
</tr>
</table>
Attempting to parse the xml like this:
$(function () {
site = 'http://ec2-54-201-216-39.us-west-2.compute.amazonaws.com/testc/WebService.asmx/GetTicker';
var yql = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent('select * from xml where url="' + site + '"') + '&format=xml&callback=?';
function loadTable() {
$.getJSON(yql, function (data) {
var xml = $.parseXML(data.results[0]),
xmlDoc = $.parseXML($(xml).find("string").text()),
$xml = $(xmlDoc),
$buyPrice = $xml.find("BuyPrice");
$volume = $xml.find("volume");
$sellPrice = $xml.find("SellPrice");
var tr;
for (var i = 0; i < xml.length; i++){
tr = $('<tr/>');
tr.append('<td>' + $buyPrice.attr("Value") + '</td>');
$('#BuyOrders').append(tr);
}
});
}
loadTable();
});
It seems you want to loop over each Ticker in the xml and add a row for each one with the relevant values:
function loadTable() {
$.getJSON(yql, function (data) {
var xml = $.parseXML(data.results[0]),
xmlDoc = $.parseXML($(xml).find("string").text()),
$xml = $(xmlDoc);
$xml.find("Ticker").each(function(){
var buyPrice = $(this).find("BuyPrice").attr("Value");
var tr = $("<tr/>");
tr.append("<td>" + buyPrice + "</td>");
/* ... any other tds here with various field values ... */
$("#BuyOrders").append(tr);
});
});
}
http://jsfiddle.net/3k7Tb/8/
I was wondering if someone could help me? In my code below what if answers in question 2 were allowed to be in any order? Like: hips,body,knees or knees,hips,body and so on. How should I modify my code? Anyone please????
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Quiz</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<script type="text/javascript">
var answer_list = [
['False'],
['body,hips,knees']
// Note: No comma after final entry
];
var response = [];
function getCheckedValue(radioObj) {
if(!radioObj)
return "";
var radioLength = radioObj.length;
if(radioLength == undefined)
if(radioObj.checked)
return radioObj.value;
else
return "";
for(var i = 0; i < radioLength; i++) {
if(radioObj[i].checked) {
return radioObj[i].value;
}
}
return "";
}
function setAnswer(question, answer) {
response[question] = answer;
}
function CheckAnswers() {
var correct = 0;
var resp, answ;
for (var i = 0; i < answer_list.length; i++) {
resp = response[i].toString();
resp = resp.toLowerCase();
answ = answer_list[i].toString();
answ = answ.toLowerCase();
//#################################################################################################
if (resp == answ) {
correct++;
if(i==0){
document.forms[0].a1c.style.backgroundImage="url('correct.gif')";
document.forms[0].a1c.value = "";
}
else{
document.forms[0].a1d.style.backgroundImage="url('correct.gif')";
document.forms[0].a1d.value = "";
}
}
else{
if(i==0){
document.forms[0].a1c.style.backgroundImage = "url('incorrect.gif')";
document.forms[0].a1c.value = " ANS: False. Position the head snugly against the top bar of the frame and then bring the foot board to the infant's feet.";
}
else{
document.forms[0].a1d.style.backgroundImage = "url('incorrect.gif')";
document.forms[0].a1d.value = " ANS: " + answ;
}
//###################################################################################################
}
}
document.writeln("You got " + correct + " of " + answer_list.length + " questions correct!");
}
</script>
</head>
<body>
<form action="" method="post">
<div>
<b>1. When measuring height/length of a child who cannot securely stand, place the infant such that his or her feet are flat against the foot board.</b><br />
<label><input type="radio" name="question0" value="True" />True</label>
<label><input type="radio" name="question0" value="False" />False</label>
<br />
<textarea rows="2" cols="85" name="a1c" style="background-repeat:no-repeat"></textarea>
<br />
<b>2. When taking a supine length measurement, straighten the infant's
<input type="text" name="question1_a" size="10" />,
<input type="text" name="question1_b" size="10" />, and
<input type="text" name="question1_c" size="10" />.</b>
<br />
<textarea rows="2" cols="85" name="a1d" style="background-repeat:no-repeat"></textarea>
<br />
<input type="button" name="check" value="Check Answers" onclick="setAnswer(0,getCheckedValue(document.forms[0].question0));setAnswer(1,[document.forms[0].question1_a.value,document.forms[0].question1_b.value,document.forms[0].question1_c.value]);CheckAnswers();" />
</div>
</form>
</body>
</html>
The easiest way IMO is to sort the user's answers and sort the correct answers in CheckAnswers().