PDA

View Full Version : Parsing XML in Javascript



jdadwilson
06-09-2016, 08:01 PM
I have an xml file formatted as follows...


<?xml version='1.0' encoding='utf-8'?>
<DeathCert>
<Item><Title>Name</Title><Data>Joe Fritz</Data><Link>12345</Link></Item>
<Item><Title>Death Date</Title><Data>Someday</Data></Item>
<Item><Title>Father</Title><Data>Bob Fritz</Data><Link>41254</Link></Item>
<Item><Title>Informant</Title<Data>Mary Fritz</Data<Show>Y</Show></Item>
</DeathCert>

I use the following code to access the elements of the file...


xmlDoc = $.parseXML( xmlDeathCert );

$('#xml_name').val(xmlDoc.getElementsByTagName('Data')[0].childNodes[0].nodeValue);
$('#xml_death_date').val(xmlDoc.getElementsByTagName('Data')[1].childNodes[0].nodeValue);
$('#xml_fathers_name').val(xmlDoc.getElementsByTagName('Data')[2].childNodes[0].nodeValue);

This works fine! The problem that I am facing is how to access the elements of 'Link' and 'Show'. I would think that the code would be...


$('#xml_name_id').val(xmlDoc.getElementsByTagName('Link')[0].childNodes[0].nodeValue);
$('#xml_fathers_id').val(xmlDoc.getElementsByTagName('Link')[1].childNodes[0].nodeValue);

Which works for the first but not for the second. Same for the 'Show' elements.

Further, I would think (it often gets me in trouble) that the access to the tree would be as such...


var Name = xmlDoc.getElementsByTagName('Item')[0].childNodes[1].nodeValue;


Representing the '0' element in the 'Item' and the 1st childnode (or 'Data').

Any assistance understanding how to access the 'Link' and 'Show' elements of the above tree will be greatly appreciated.

TIA
jdadwilson

jscheuer1
06-09-2016, 09:26 PM
That xml is invalid, it's missing two closing angle brackets on line 6:


<Item><Title>Informant</Title<Data>Mary Fritz</Data<Show>Y</Show></Item>

Should be:


<Item><Title>Informant</Title><Data>Mary Fritz</Data><Show>Y</Show></Item>

There could also be other problems, but there's a good chance that's it. In any case, that must be fixed before you can effectively parse it as an xml document. I'm surprised you were even able to get the information from it that you were. But it's also possible that the elements you want to write to, like $('#xml_fathers_id') don't exist at that point and/or cannot be written to using .val()

Oh, and for your very last question, this works (you left out a level):


xmlDoc.getElementsByTagName('Item')[0].childNodes[1].childNodes[0].nodeValue

If you want more help, please post a link to the page on your site where you have the problem code so we can check it out.

Working Demo:


<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<label>Name: <input type="text" id="xml_name"></label><br>
<label>Death Date: <input type="text" id="xml_death_date"></label><br>
<label>Father's Name: <input type="text" id="xml_fathers_name"></label><br>
<label>Name ID: <input type="text" id="xml_name_id"></label><br>
<label>Father's Name ID: <input type="text" id="xml_fathers_id"></label>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
var xmlDeathCert = "<?xml version='1.0' encoding='utf-8'?>\n" +
"<DeathCert>\n" +
"<Item><Title>Name</Title><Data>Joe Fritz</Data><Link>12345</Link></Item>\n" +
"<Item><Title>Death Date</Title><Data>Someday</Data></Item>\n" +
"<Item><Title>Father</Title><Data>Bob Fritz</Data><Link>41254</Link></Item>\n" +
"<Item><Title>Informant</Title><Data>Mary Fritz</Data><Show>Y</Show></Item>\n" +
"</DeathCert>",
xmlDoc = $.parseXML( xmlDeathCert );
$('#xml_name').val(xmlDoc.getElementsByTagName('Data')[0].childNodes[0].nodeValue);
$('#xml_death_date').val(xmlDoc.getElementsByTagName('Data')[1].childNodes[0].nodeValue);
$('#xml_fathers_name').val(xmlDoc.getElementsByTagName('Data')[2].childNodes[0].nodeValue);
$('#xml_name_id').val(xmlDoc.getElementsByTagName('Link')[0].childNodes[0].nodeValue);
$('#xml_fathers_id').val(xmlDoc.getElementsByTagName('Link')[1].childNodes[0].nodeValue);
</script>
</body>
</html>

jdadwilson
06-10-2016, 12:45 AM
My Bad... I typed the xml rather than making a copy from the database (contains sensitive information). Here is the javascript code I use...


xmlDoc = $.parseXML( xmlDeathCert );

var lookFor = xmlDoc.getElementsByTagName('Collection')[0].childNodes[0].nodeValue;
var lookIn = document.getElementById('xml_collection');
selectItemByValue(lookIn, lookFor);

$('#xml_name').val(xmlDoc.getElementsByTagName('Data')[0].childNodes[0].nodeValue);
$('#xml_death_date').val(xmlDoc.getElementsByTagName('Data')[1].childNodes[0].nodeValue);
$('#xml_death_place').val(xmlDoc.getElementsByTagName('Data')[2].childNodes[0].nodeValue);

lookFor = xmlDoc.getElementsByTagName('Data')[3].childNodes[0].nodeValue;
lookIn = document.getElementById('xml_gender');
selectItemByValue(lookIn, lookFor);

$('#xml_race').val(xmlDoc.getElementsByTagName('Data')[4].childNodes[0].nodeValue);
$('#xml_death_age').val(xmlDoc.getElementsByTagName('Data')[5].childNodes[0].nodeValue);

$('#xml_est_birth_date').val(xmlDoc.getElementsByTagName('Data')[6].childNodes[0].nodeValue);
$('#xml_birth_date').val(xmlDoc.getElementsByTagName('Data')[7].childNodes[0].nodeValue);
$('#xml_birth_place').val(xmlDoc.getElementsByTagName('Data')[8].childNodes[0].nodeValue);

lookFor = xmlDoc.getElementsByTagName('Data')[9].childNodes[0].nodeValue;
lookIn = document.getElementById('xml_marital_status');
selectItemByValue(lookIn, lookFor);

$('#xml_spouses_name').val(xmlDoc.getElementsByTagName('Data')[10].childNodes[0].nodeValue);
$('#xml_spouses_id').val(xmlDoc.getElementsByTagName('Link')[0].childNodes[0].nodeValue);

$('#xml_fathers_name').val(xmlDoc.getElementsByTagName('Data')[11].childNodes[0].nodeValue);
$('#xml_fathers_birth_place').val(xmlDoc.getElementsByTagName('Data')[12].childNodes[0].nodeValue);

$('#xml_mothers_name').val(xmlDoc.getElementsByTagName('Data')[13].childNodes[0].nodeValue);
$('#xml_mothers_birth_place').val(xmlDoc.getElementsByTagName('Data')[14].childNodes[0].nodeValue);

$('#xml_occupation').val(xmlDoc.getElementsByTagName('Data')[15].childNodes[0].nodeValue);
$('#xml_residence').val(xmlDoc.getElementsByTagName('Data')[16].childNodes[0].nodeValue);

$('#xml_cemetery').val(xmlDoc.getElementsByTagName('Data')[17].childNodes[0].nodeValue);
$('#xml_burial_place').val(xmlDoc.getElementsByTagName('Data')[18].childNodes[0].nodeValue);
$('#xml_burial_date').val(xmlDoc.getElementsByTagName('Data')[19].childNodes[0].nodeValue);

$('#xml_af_organization').val(xmlDoc.getElementsByTagName('Data')[20].childNodes[0].nodeValue);
$('#xml_next_kin').val(xmlDoc.getElementsByTagName('Data')[21].childNodes[0].nodeValue);
$('#xml_informant').val(xmlDoc.getElementsByTagName('Data')[22].childNodes[0].nodeValue);

$('#xml_image_number').val(xmlDoc.getElementsByTagName('Data')[23].childNodes[0].nodeValue);
$('#xml_cert_number').val(xmlDoc.getElementsByTagName('Data')[24].childNodes[0].nodeValue);


Note that the highlighted line causes an error and thus stops the processing.

Here is the html...


<input type="text" id="xml_spouses_id" name="xml_spouses_id" class="form-control" maxlength="5" tabindex="46" value="" placeholder="NNNNN" />

According to your reply this should work. Everything else works fine.

Thanks for your help.
jdadwilson

jscheuer1
06-10-2016, 02:08 AM
Well, apparently you are not sharing your xml file nor your page, which is fine - except there's likely little way to determine the cause for the error without one or the other, perhaps both. Well other than what I've already mentioned - if that's of any use for you looking over what you actually have.

I could PM you my email address and you could, if you so desire, attach the actual files or a link to them.

Alternatively, you could try simply removing the offending line, it appears (as you say) incorrect anyway - given what you originally indicate to be the xml document's structure (what you call the offending line):


xmlDoc.getElementsByTagName('Link')[0].childNodes[0].nodeValue

mmmm, would concern this line:


<Item><Title>Name</Title><Data>Joe Fritz</Data><Link>12345</Link></Item>

Nothing to do with the spouse. However, (in any case) this code (repeating):


xmlDoc.getElementsByTagName('Link')[0].childNodes[0].nodeValue

Would work like so:

xmlDoc - is the entire xml doc.

xmlDoc.getElementsByTagName('Link')[0] - is:


<Item><Title>Name</Title><Data>Joe Fritz</Data><Link>12345</Link></Item>

xmlDoc.getElementsByTagName('Link')[0].childNodes[0].nodeValue - is:


<Item><Title>Name</Title><Data>Joe Fritz</Data><Link>12345</Link></Item>

If you're not getting that, there's a problem. If your xml document doesn't have anything there that fits that query, there's also a problem.

It might be something else. I really have to see the relevant pages/files/code to know for sure.

jdadwilson
06-10-2016, 04:57 AM
Sorry, I forgot about your request for the files. BUT, now it is working. Don't know why, but it is. Here is what I did.

I copied/pasted the one line with the ('Link') code from your demo into my code and changed the $('#xxx') and [x] parameters. Inspection showed that your code and mine were the same. But yours worked. Might have been something that DreamWeaver was causing (its happened before).

Once again, I am indebted to you for your assistance.
jdadwilson

jscheuer1
06-10-2016, 05:02 AM
As long as it's working, we're happy. From what you say, perhaps the error was arising from a previously cached version of one or more of the files involved.

jscheuer1
06-11-2016, 06:01 AM
I've been playing with this a bit more. It turns out that the word 'Link' (or 'link', either way) is sort of reserved, so is a poor choice for a tag name. That may or may not be contributing to your uneven/illogical results. I would though suggest changing it to - say 'Refnum', or 'Id', as those seem more descriptive and are apparently not reserved words, at least not in this context.

But upon further examination, that's only if the document/text isn't first parsed as xml. So 'Link'/'link' can be used.

In any case, I also was wondering why you weren't using jQuery more (since you are using it to parse the xml). As a result, I came up with this interesting demo:


<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<label>Name: <input type="text" id="xml_name"></label><br>
<label>Death Date: <input type="text" id="xml_death_date"></label><br>
<label>Father's Name: <input type="text" id="xml_fathers_name"></label><br>
<label>Name ID: <input type="text" id="xml_name_id"></label><br>
<label>Father's Name ID: <input type="text" id="xml_fathers_id"></label>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
var xmlDeathCert = "<?xml version='1.0' encoding='utf-8'?>\n" +
"<DeathCert>\n" +
"<Item><Title>Name</Title><Data>Joe Fritz</Data><Link>12345</Link></Item>\n" +
"<Item><Title>Death Date</Title><Data>Someday</Data></Item>\n" +
"<Item><Title>Father</Title><Data>Bob Fritz</Data><Link>41254</Link></Item>\n" +
"<Item><Title>Informant</Title><Data>Mary Fritz</Data><Show>Y</Show></Item>\n" +
"</DeathCert>",
xmlDoc = $.parseXML( xmlDeathCert );
function getTagValFromTilte(title, tag, doc){
var $titles = $('Title', $(doc)), rval;
$titles.each(function(i, t){
if($(t).text() === title){
rval = $(t).siblings(tag).text();
return false;
}
});
return rval;
}
$('#xml_name').val(getTagValFromTilte('Name', 'Data', xmlDoc));
$('#xml_death_date').val(getTagValFromTilte('Death Date', 'Data', xmlDoc));
$('#xml_fathers_name').val(getTagValFromTilte('Father', 'Data', xmlDoc));
$('#xml_name_id').val(getTagValFromTilte('Name', 'Link', xmlDoc));
$('#xml_fathers_id').val(getTagValFromTilte('Father', 'Link', xmlDoc));
</script>
</body>
</html>