I'm trying to setup a form to allow people modifying some parts of XML files, using standard inputs/textareas/checkboxes, etc; and see the corresponding XML file modified in "real time", in their browser (so using JS)
What I have been doing so far is have an attribute on each form element that stores an XPath to see which XML node/text the input corresponds to.
I can get the xpath value from the XML, but them I'm unable to modify the corresponding XML.
Here is the code :
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
function updateXml(input) {
newvalue = $(input).val();
xmlStr = $("#xml" ).val();
if(xmlStr=="" ) return;
xmlObj = $.parseXML(xmlStr);
xpath = $(input).attr('data-xpath');
result = xmlObj.evaluate(xpath, xmlObj, null, XPathResult.ANY_TYPE, null);
element = result.iterateNext();
//element is a copy of the noden I can't modify it directly, it won't be reflected in xmlObj...
//this will work in my example, but it's too "hardcoded", I want to change that using xpath
xmlObj.getElementsByTagName("person" )[0].getElementsByTagName("name" )[0].innerHTML = newvalue;
var xmlText = new XMLSerializer().serializeToString(xmlObj);
$("#xml" ).val(xmlText);
}
</script>
<form>
<input onkeyup="updateXml(this);" data-xpath="/person/name" />
<textarea id="xml" style="width: 800px;height: 600px;">
<?xml version="1.0" encoding="ISO-8859-1"?>
<person>
<name>Paul</name>
<age>12</age>
</person>
</textarea>
</form>
In other words, I would like to be able to change the "age" using another input field, without changing the code...
Any idea how I can do this ? or another (simple) way of doing it ?
Thanks !
Your basic idea is correct: manipulate the document using the XML DOM elements, then serialize back and update the textarea.
The sample code below is still incomplete and needs some polishment before it can go to production. However, I think I have added a lot of useful code and demonstrated how it can be done!
function getElementsByXPath(xpath, elt, val)
{
var results = [];
var nsResolver = document.createNSResolver( elt.ownerDocument == null ? elt.documentElement : elt.ownerDocument.documentElement );
var xPathRes = document.evaluate(xpath, elt, nsResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0; i < xPathRes.snapshotLength; i++) {
var element = xPathRes.snapshotItem (i);
if (element instanceof Attr) { results.push(val); }//element.nodeValue);
else if (element instanceof Element && element.outerHTML) { element.innerHTML = val;
results.push(element.outerHTML);}
else results.push(element); //TODO
}
return results;
}
function updateXml(input) {
newvalue = $(input).val();
xmlStr = $("#xml" ).val();
if(xmlStr=="" ) return;
var xml = (new DOMParser()).parseFromString(xmlStr, "text/xml");
var xpath = $(input).attr('data-xpath');
var results = getElementsByXPath(xpath, xml, newvalue);
/*var ResultTxt = '';
results.forEach(function(result) {
ResultTxt += result + "\n";
});
$("#result" ).val(ResultTxt);
console.log(ResultTxt);*/
var xmlText = new XMLSerializer().serializeToString(xml);
$("#xml" ).val(xmlText);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
<form>
<input onkeyup="updateXml(this);" data-xpath="/person/name" />
<textarea id="xml" style="width: 800px;height: 200px;">
<?xml version="1.0" encoding="ISO-8859-1"?>
<person>
<name>Paul</name>
<age>12</age>
</person>
</textarea>
</form>
</body>
</html>
Related
I'm quite new on XML and JS, so please forgive me if the question is trivial.
What I'm trying to do, is parsing an XML and collect all the nodes tagged with the value "name". After that, I want to put them in a table (I haven't developed the table part).
Below is an excerpt from the parsed XML:
`
<?xml version="1.0" encoding="UTF-8"?>
<model-data>
<identification>
<date>Thu Dec 15 14:43:07 CET 2022</date>
<xml-version>4.11</xml-version>
</identification>
<model>
<named-domains>
<named-domain>
<name>boolean</name>
<elements>
<element>
<value>0</value>
<name>No</name>
<description>No</description>
</element>
<element>
<value>1</value>
<name>Yes</name>
<description>Yes</description>
</element>
</elements>
</named-domain>
<named-domain>
<name>D_NOME_TECNICO_COMPLETO</name>
<elements>
<element>
<value>0</value>
<name>PippoBaudo</name>
<description>Superstar</description>
</element>
... // same pattern
</elements>
</named-domain>
</named-domains>
</model>
</model-data>
`
And here the JS code:
`
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
showResult(xhttp.responseXML);
}
};
xhttp.open("GET", "prova.xml", true);
xhttp.send();
function showResult(xml) {
var txt = "";
// path = "//named-domain/name[text()]";
path = "/model-data/model/named-domains//name[text()]";
if (xml.evaluate) {
var nodes = xml.evaluate(path, xml, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
var result = nodes.iterateNext();
while (result) {
txt += "<b>" + result.childNodes[0].nodeValue + "</b><br>";
result = nodes.iterateNext();
parente = nodes.parentnode.nodevalue; // <- Here something goes wrong!
}
// Code For Internet Explorer
} else if (window.ActiveXObject || xhttp.responseType == "msxml-document") {
xml.setProperty("SelectionLanguage", "XPath");
nodes = xml.selectNodes(path);
for (i = 0; i < nodes.length; i++) {
txt += nodes[i].childNodes[0].nodeValue + "<br>";
}
}
document.getElementById("demo").innerHTML = txt;
}
</script>
</body>
</html>
`
What I need, is to intercept the childnodes of nodes whose value is "named-domain" and to treat them in some ways. I tried to catch the parent node with "parente = nodes.parentnode.nodevalue" but:
VS code doesn't suggest me the property parentnode for the element "nodes", and I don't understand why;
If I *force *the property by hand, I receive the following error: "Uncaught TypeError: Cannot read properties of undefined (reading 'nodeValue')". Again: why?
Someone may help me?
Thank you
It is parentNode, not parentnode. nodeValue in the DOM is not giving anything meaningful for element nodes.
I have the following tag in my view.jsp:
<liferay-ui:input-localized id="message" name="message" xml="" />
And I know that I can set a XML and have a default value on my input localized. My problem is that I want to change this attribute with javascript. I am listening for some changes and call the function "update()" to update my information:
function update(index) {
var localizedInput= document.getElementById('message');
localizedInput.value = 'myXMLString';
}
Changing the value is only updating the currently selected language input (with the whole XML String). The XML String is correct, but I am not sure on how to update the XML for the input with javascript.
Is this possible?
PS: I have posted this in the Liferay Dev forum to try and reach more people.
After a week of studying the case and some tests, I think that I found a workaround for this. Not sure if this is the correct approach, but it is working for me so I will post my current solution for future reference.
After inspecting the HTML, I noticed that the Liferay-UI:input-localized tag creates an input tag by default, and then one more input tag for each language, each time you select a new language. Knowing that I created some functions with Javascript to help me update the inputs created from my liferay-ui:input-localized. Here is the relevant code:
function updateAnnouncementInformation(index) {
var announcement = announcements[index];
// the announcement['message'] is a XML String
updateInputLocalized('message', announcement['message']);
}
function updateInputLocalized(input, message) {
var inputId = '<portlet:namespace/>' + input;
var xml = $.parseXML(message);
var inputCurrent = document.getElementById(inputId);
var selectedLanguage = getSelectedLanguage(inputId);
var inputPT = document.getElementById(inputId + '_pt_PT');
inputPT.value = $(xml).find("Title[language-id='pt_PT']").text();
var inputEN = document.getElementById(inputId + '_en_US');
if (inputEN !== null) inputEN.value = $(xml).find("Title[language-id='en_US']").text();
else waitForElement(inputId + '_en_US', inputCurrent, inputId, xml);
var inputLabel = getInputLabel(inputId);
if (selectedLanguage == 'pt-PT') inputLabel.innerHTML = '';
else inputLabel.innerHTML = inputPT.value;
if (selectedLanguage == 'pt-PT') inputCurrent.value = inputPT.value;
else if (inputEN !== null) inputCurrent.value = inputEN.value;
else waitForElement(inputId + '_en_US', inputCurrent, inputId, xml);
}
function getSelectedLanguage(inputId) {
var languageContainer = document.getElementById('<portlet:namespace/>' + inputId + 'Menu');
return languageContainer.getElementsByClassName('btn-section')[0].innerHTML;
}
function getInputLabel(inputId) {
var boundingBoxContainer = document.getElementById(inputId + 'BoundingBox').parentElement;
return boundingBoxContainer.getElementsByClassName('form-text')[0];
}
function waitForElement(elementId, inputCurrent, inputId, xml) {
window.setTimeout(function() {
var element = document.getElementById(elementId);
if (element) elementCreated(element, inputCurrent, inputId, xml);
else waitForElement(elementId, inputCurrent, inputId, xml);
}, 500);
}
function elementCreated(inputEN, inputCurrent, inputId, xml) {
inputEN.value = $(xml).find("Title[language-id='en_US']").text();
var selectedLanguage = getSelectedLanguage(inputId);
if (selectedLanguage == 'en-US') inputCurrent.value = inputEN.value;
}
With this I am able to update the liferay-ui:input-localized inputs according to a pre-built XML String. I hope that someone finds this useful and if you have anything to add, please let me know!
To change the text value of an element, you must change the value of the elements's text node.
Example -
xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue = "new content"
Suppose "books.xml" is loaded into xmlDoc
Get the first child node of the element
Change the node value to "new content"
I have a below piece of code which is working only with IE because of active X parser and I need to run it in chrome and other latest browsers.
< script language = "jscript" type = "text/javascript" >
function Transform1() {
var xml1 = new ActiveXObject("Microsoft.XMLDOM");
xml1.async = false; xml1.load(frmSoap.TestXml.value);
frmSoap.Body.value = xml1.xml;
}
< /script>
I tried to fix it by using the below change but it did not work for me and instead stopped working in ie as well.
function Transform1()
if (window.DOMParser) {
var parser, xml1;
parser = new DOMParser();
xml1 = parser.parseFromString(frmSoap.TestXml.value,"text/xml");
frmSoap.Body.value = xml1.xml;
} else {
var xml1 = new ActiveXObject("Microsoft.>XMLDOM");
xml1.async = false;
xml1.load(frmSoap.TestXml.value);
frmSoap.Body.value = xml1.xml;
}
Can somebody help me fix this issue.
Here is an approach that will work for you in all browsers. This is through the use of createDocument() and then having the browser parse the XML for you.
Please refer to the comments in the code.
//Mock
const frmSoap = {
TestXml: {
value: `<productListing title="ABC Products">
<product>
<name>Product One</name>
<description>Product One is an exciting new widget that will
simplify your life.</description>
<cost>$19.95</cost>
<shipping>$2.95</shipping>
</product>
</productListing>`
}
}
// Create an XHTML document
var doc = document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'xhtml', null);
// Add body
var body = document.createElementNS('http://www.w3.org/1999/xhtml', 'body');
doc.documentElement.appendChild(body);
// Parse the XML document and place it in the new XML doc body
body.innerHTML = frmSoap.TestXml.value;
//Parse the XML to produce output
const title = body.querySelector('productListing').getAttribute('title');
const productName = body.querySelector("product name").textContent;
const productDescription = body.querySelector("product description").textContent;
//Use the XML data
document.getElementById("output").innerHTML = `<h1>${title}</h1><span>Product Name:</span> ${productName}, <br><span>Product Description:</span> ${productDescription}`;
// Remove the doc when no longer needed
doc = null;
span {
font-weight: bold;
}
<div id="output"></div>
I'd like to save the html string of the DOM, and later restore it to be exactly the same. The code looks something like this:
var stringified = document.documentElement.innerHTML
// later, after serializing and deserializing
document.documentElement.innerHTML = stringified
This works when everything is perfect, but when the DOM is not w3c-comliant, there's a problem. The first line works fine, stringified matches the DOM exactly. But when I restore from the (non-w3c-compliant) stringified, the browser does some magic and the resulting DOM is not the same as it was originally.
For example, if my original DOM looks like
<p><div></div></p>
then the final DOM will look like
<p></p><div></div><p></p>
since div elements are not allowed to be inside p elements. Is there some way I can get the browser to use the same html parsing that it does on page load and accept broken html as-is?
Why is the html broken in the first place? The DOM is not controlled by me.
Here's a jsfiddle to show the behavior http://jsfiddle.net/b2x7rnfm/5/. Open your console.
<body>
<div id="asdf"><p id="outer"></p></div>
<script type="text/javascript">
var insert = document.createElement('div');
var text = document.createTextNode('ladygaga');
insert.appendChild(text);
document.getElementById('outer').appendChild(insert);
var e = document.getElementById('asdf')
console.log(e.innerHTML);
e.innerHTML = e.innerHTML;
console.log(e.innerHTML); // This is different than 2 lines above!!
</script>
</body>
If you need to be able to save and restore an invalid HTML structure, you could do it by way of XML. The code which follows comes from this fiddle.
To save, you create a new XML document to which you add the nodes you want to serialize:
var asdf = document.getElementById("asdf");
var outer = document.getElementById("outer");
var add = document.getElementById("add");
var save = document.getElementById("save");
var restore = document.getElementById("restore");
var saved = undefined;
save.addEventListener("click", function () {
if (saved !== undefined)
return; /// Do not overwrite
// Create a fake document with a single top-level element, as
// required by XML.
var parser = new DOMParser();
var doc = parser.parseFromString("<top/>", "text/xml");
// We could skip the cloning and just move the nodes to the XML
// document. This would have the effect of saving and removing
// at the same time but I wanted to show what saving while
// preserving the data would look like
var clone = asdf.cloneNode(true);
var top = doc.firstChild;
var child = asdf.firstChild;
while (child) {
top.appendChild(child);
child = asdf.firstChild;
}
saved = top.innerHTML;
console.log("saved as: ", saved);
// Perform the removal here.
asdf.innerHTML = "";
});
To restore, you create an XML document to deserialize what you saved and then add the nodes to your document:
restore.addEventListener("click", function () {
if (saved === undefined)
return; // Don't restore undefined data!
// We parse the XML we saved.
var parser = new DOMParser();
var doc = parser.parseFromString("<top>" + saved + "</top>", "text/xml");
var top = doc.firstChild;
var child = top.firstChild;
while (child) {
asdf.appendChild(child);
// Remove the extra junk added by the XML parser.
child.removeAttribute("xmlns");
child = top.firstChild;
}
saved = undefined;
console.log("inner html after restore", asdf.innerHTML);
});
Using the fiddle, you can:
Press the "Add LadyGaga..." button to create the invalid HTML.
Press "Save and Remove from Document" to save the structure in asdf and clear its contents. This prints to the console what was saved.
Press "Restore" to restore the structure that was saved.
The code above aims to be general. It would be possible to simplify the code if some assumptions can be made about the HTML structure to be saved. For instance blah is not a well-formed XML document because you need a single top element in XML. So the code above takes pains to add a top-level element (top) to prevent this problem. It is also generally not possible to just parse an HTML serialization as XML so the save operation serializes to XML.
This is a proof-of-concept more than anything. There could be side-effects from moving nodes created in an HTML document to an XML document or the other way around that I have not anticipated. I've run the code above on Chrome and FF. I don't have IE at hand to run it there.
This won't work for your most recent clarification, that you must have a string copy. Leaving it, though, for others who may have more flexibility.
Since using the DOM seems to allow you to preserve, to some degree, the invalid structure, and using innerHTML involves reparsing with (as you've observed) side-effects, we have to look at not using innerHTML:
You can clone the original, and then swap in the clone:
var e = document.getElementById('asdf')
snippet.log("1: " + e.innerHTML);
var clone = e.cloneNode(true);
var insert = document.createElement('div');
var text = document.createTextNode('ladygaga');
insert.appendChild(text);
document.getElementById('outer').appendChild(insert);
snippet.log("2: " + e.innerHTML);
e.parentNode.replaceChild(clone, e);
e = clone;
snippet.log("3: " + e.innerHTML);
Live Example:
var e = document.getElementById('asdf')
snippet.log("1: " + e.innerHTML);
var clone = e.cloneNode(true);
var insert = document.createElement('div');
var text = document.createTextNode('ladygaga');
insert.appendChild(text);
document.getElementById('outer').appendChild(insert);
snippet.log("2: " + e.innerHTML);
e.parentNode.replaceChild(clone, e);
e = clone;
snippet.log("3: " + e.innerHTML);
<div id="asdf">
<p id="outer">
<div>ladygaga</div>
</p>
</div>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Note that just like the innerHTML solution, this will wipe out event handlers on the elements in question. You could preserve handlers on the outermost element by creating a document fragment and cloning its children into it, but that would still lose handlers on the children.
This earlier solution won't apply to you, but may apply to others in the future:
My earlier solution was to track what you changed, and undo the changes one-by-one. So in your example, that means removing the insert element:
var e = document.getElementById('asdf')
console.log("1: " + e.innerHTML);
var insert = document.createElement('div');
var text = document.createTextNode('ladygaga');
insert.appendChild(text);
var outer = document.getElementById('outer');
outer.appendChild(insert);
console.log("2: " + e.innerHTML);
outer.removeChild(insert);
console.log("3: " + e.innerHTML);
var e = document.getElementById('asdf')
snippet.log("1: " + e.innerHTML);
var insert = document.createElement('div');
var text = document.createTextNode('ladygaga');
insert.appendChild(text);
var outer = document.getElementById('outer');
outer.appendChild(insert);
snippet.log("2: " + e.innerHTML);
outer.removeChild(insert);
snippet.log("3: " + e.innerHTML);
<div id="asdf">
<p id="outer">
<div>ladygaga</div>
</p>
</div>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Try utilizing Blob , URL.createObjectURL to export html ; include script tag in exported html which removes <div></div><p></p> elements from rendered html document
html
<body>
<div id="asdf">
<p id="outer"></p>
</div>
<script>
var insert = document.createElement("div");
var text = document.createTextNode("ladygaga");
insert.appendChild(text);
document.getElementById("outer").appendChild(insert);
var elem = document.getElementById("asdf");
var r = document.querySelectorAll("[id=outer] ~ *");
// remove last `div` , `p` elements from `#asdf`
for (var i = 0; i < r.length; ++i) {
elem.removeChild(r[i])
}
</script>
</body>
js
var e = document.getElementById("asdf");
var html = e.outerHTML;
console.log(document.body.outerHTML);
var blob = new Blob([document.body.outerHTML], {
type: "text/html"
});
var objUrl = window.URL.createObjectURL(blob);
var popup = window.open(objUrl, "popup", "width=300, height=200");
jsfiddle http://jsfiddle.net/b2x7rnfm/11/
see this example: http://jsfiddle.net/kevalbhatt18/1Lcgaprc/
MDN cloneNode
var e = document.getElementById('asdf')
console.log(e.innerHTML);
backupElem = e.cloneNode(true);
// Your tinkering with the original
e.parentNode.replaceChild(backupElem, e);
console.log(e.innerHTML);
You can not expect HTML to be parsed as a non-compliant HTML. But since the structure of compiled non-compliant HTML is very predictable you can make a function which makes the HTML non-compliant again like this:
function ruinTheHtml() {
var allElements = document.body.getElementsByTagName( "*" ),
next,
afterNext;
Array.prototype.map.call( allElements,function( el,i ){
if( el.tagName !== 'SCRIPT' && el.tagName !== 'STYLE' ) {
if(el.textContent === '') {
next = el.nextSibling;
afterNext = next.nextSibling;
if( afterNext.textContent === '' ) {
el.parentNode.removeChild( afterNext );
el.appendChild( next );
}
}
}
});
}
See the fiddle:
http://jsfiddle.net/pqah8e25/3/
You have to clone the node instead of copying html. Parsing rules will force the browser to close p when seeing div.
If you really need to get html from that string and it is valid xml, then you can use following code ($ is jQuery):
var html = "<p><div></div></p>";
var div = document.createElement("div");
var xml = $.parseXML(html);
div.appendChild(xml.documentElement);
div.innerHTML === html // true
You can use outerHTML, it perseveres the original structure:
(based on your original sample)
<div id="asdf"><p id="outer"></p></div>
<script type="text/javascript">
var insert = document.createElement('div');
var text = document.createTextNode('ladygaga');
insert.appendChild(text);
document.getElementById('outer').appendChild(insert);
var e = document.getElementById('asdf')
console.log(e.outerHTML);
e.outerHTML = e.outerHTML;
console.log(e.outerHTML);
</script>
Demo: http://jsfiddle.net/b2x7rnfm/7
I am developing an app, where on the click of a button, a list of the document information stored in an XML file is shown on screen in a <ul> tag. The current JavaScript in the function is;
function viewXMLFiles() {
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "TestInfo.xml", false);
xmlhttp.send();
xmlDoc = xmlhttp.responseXML;
document.getElementById("docname").innerHTML = xmlDoc.getElementsByTagName("document_name")[0].childNodes[0].nodeValue;
document.getElementById("filetype").innerHTML = xmlDoc.getElementsByTagName("file_type")[0].childNodes[0].nodeValue;
document.getElementById("fileloc").innerHTML = pathToRoot + "/" + document.getElementById("docname").innerHTML;
document.getElementById("docname1").innerHTML = xmlDoc.getElementsByTagName("document_name")[1].childNodes[0].nodeValue;
document.getElementById("filetype1").innerHTML = xmlDoc.getElementsByTagName("file_type")[1].childNodes[0].nodeValue;
document.getElementById("fileloc1").innerHTML = pathToRoot + "/" + document.getElementById("docname1").innerHTML;
}
but i want to set it so that even if more file information is added, the function will display it too. i have already looked at Jquery xml parsing loops this question, but i couldn't get the function to work. Here's the XML file;
<document_list>
<document>
<document_name>Holidays.pdf</document_name><br />
<file_type>.pdf</file_type> <br />
<file_location>TEST</file_location> <br />
</document>
<document>
<document_name>iPhone.jsNotes.docx</document_name><br />
<file_type>.docx</file_type><br />
<file_location>TEST</file_location><br />
</document>
</document_list>
And this is the HTML i am using. There's a button and the <ul> tags i'm using;
<button onclick = "viewXMLFiles(); document.getElementById('showDocumentLink').style.display = 'block';">View Document Info</button><br>
<div id = "doclist">
<h2>Document 1;</h2>
<label>Document Name;</label><br><span id = "docname"></span><br>
<label>File Type</label><br><span id = "filetype"></span><br>
<label>File Location</label><br><span id = "fileloc"></span><br>
</div>
<div id = "doclist">
<h2>Document 2;</h2>
<label>Document Name;</label><br><span id = "docname1"></span><br>
<label>File Type</label><br><span id = "filetype1"></span><br>
<label>File Location</label><br><span id = "fileloc1"></span><br>
</div>
Can anyone help me put this into a loop? I have linked jQuery and jQTouch so i can use both of them.
Thank you so much in advance xx
Use following loop code.
<script>
xmlDoc = $.parseXML( xml ),
$xml = $( xmlDoc );
var documents = $xml.find('document_list');
documents.children('document').each(function() {
var name = $(this).find('document_name').text();
var file_type = $(this).find('file_type').text();
var file_location = $(this).find('file_location').text();
// now do whatever you like with above variable
});
</script>
Using Irfan's answer as a base, to get the values into your labels add a counter, then just insert the values grabbed from the XML parsing loop into the corresponding span.
<script>
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "TestInfo.xml", false);
xmlhttp.send();
xmlDoc = xmlhttp.responseXML;
$xml = $( xmlDoc );
var documents = $xml.find('document_list');
var doccount = 0;
//will be used to find the HTML elements
var namelabel = "docname";
var typelabel = "filetype";
var locationlabel = "fileloc";
documents.children('document').each(function() {
var name = $(this).find('document_name').text();
var file_type = $(this).find('file_type').text();
var file_location = $(this).find('file_location').text();
//after the first document we need to add the number to the span id
if(doccount > 0){
namelabel = "docname" + doccount;
typelabel = "filetype" + doccount;
locationlabel = "fileloc" + doccount;
}
//insert the XML values into the label
$('span#'+namelabel).html(name);
$('span#'+typelabel).html(file_type);
$('span#'+locationlabel).html(file_location);
//increment the counter
doccount++;
});
</script>
Here is a native JavaScript implementation so you can see how you'd do it that way and compare, etc.
function viewXMLFiles() {
// var everything
var xmlhttp = new XMLHttpRequest(),
xmlDoc,
nodes, i, j, counter = -1, suffix,
document_name, file_type, file_location;
// request page
xmlhttp.open("GET", "TestInfo.xml", false),
xmlhttp.send();
// false meant synchronous req. so can go straight to reading document
xmlDoc = xmlhttp.responseXML;
// loop over <document> nodes
nodes = xmlDoc.childNodes; // shorthand
j = nodes.length;
for (i = 0; i < j; ++i) {
if ('document' === nodes[i].tagName.toLowerCase()) {
// nodes[i] is a <document>, increment counter
++counter;
// get nodes of intrest
document_name = nodes[i].getElementsByTagName("document_name")[0];
file_type = nodes[i].getElementsByTagName("file_type")[0];
file_location = nodes[i].getElementsByTagName("file_location")[0];
// do what you want with these, e.g.
suffix = counter || ''; // don't append a number for 0
document.getElementById('docname'+suffix).textContent = document_name.textContent;
document.getElementById('filetype'+suffix).textContent = file_type.textContent;
document.getElementById('fileloc'+suffix).textContent = pathToRoot + "/" + file_location.textContent;
}
}
}
Furthermore, you should consider the validity of your HTML, as I mentioned in my comment;
there should be no spaces around the equals sign of an attribute name/value pair, i.e. <tag attrib="val"/> not <tag attrib = "val"/>
every id attribute should have a unique value, not shared with any other on the document, i.e. not <tag id="shared"/><tag id="shared"/>