I am having trouble loading values from an XML file and inserting them into a HTML table. It says that the html tag I am attempting to access is undefined "script.js:15 Uncaught TypeError: Cannot read property 'getElementsByTagName' of undefined". I am trying to insert the values of and into a html table from the loaded XML file.
// script.js
function loadXMLDoc() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
myFunction(this);
}
};
xmlhttp.open("GET", "table.xml", true);
xmlhttp.send();
}
function myFunction() {
var xmlDoc = XMLHttpRequest.responseXML;
var table = '<tr><th>Name</th><th>Age</th></tr>';
var x = xmlDoc.getElementsByTagName('STUDENT');
for (i = 0; i < x.length; i++) {
table += "<tr><td>" +
x[i].getElementsByTagName("NAME")[0].childNodes[0].nodeValue +
"</td><td>" +
x[i].getElementsByTagName("AGE")[0].childNodes[0].nodeValue +
"</td></tr>";
}
document.getElementById("students") = table;
}
//relevant html
<body>
<br><br>
<table id="students"></table>
<script src="script.js"></script>
</body>
//XML Doc Contents
<CLASS ID=”Advanced Web Development”>
<STUDENT>
<NAME>Tom</NAME>
<AGE>19</AGE>
<HEIGHT>1.3</HEIGHT>
<SEX>M</SEX>
<GRADE>B</GRADE>
</STUDENT>
<STUDENT>
<NAME>Dick</NAME>
<AGE>29</AGE>
<HEIGHT>1.1</HEIGHT>
<SEX>M</SEX>
<GRADE>A</GRADE>
</STUDENT>
<STUDENT>
<NAME>Harry</NAME>
<AGE>39</AGE>
<HEIGHT>1.5</HEIGHT>
<SEX>M</SEX>
<GRADE>C</GRADE>
</STUDENT>
<STUDENT>
<NAME>Mary</NAME>
<AGE>30</AGE>
<HEIGHT>1.1</HEIGHT>
<SEX>F</SEX>
<GRADE>B+</GRADE>
</STUDENT>
</CLASS>
There appears to be a few things you aren't quite doing right here:
Firstly, the XMLHttpRequest class doesn't have a responseXML property: that isn't where to get the result of an asynchronous request. Instead, the responseXML property belongs to the individual XMLHttpRequest objects (or 'instances'). You create a new XMLHttpRequest instance in the variable xmlhttp in the line var xmlhttp = new XMLHttpRequest();, and it will be xmlhttp that contains the responseXML property.
Additionally, you are passing the value of this in your onreadystatechange handler to myFunction, but myFunction doesn't take any arguments. JavaScript has very lax restrictions on calling functions with the correct number of arguments: any surplus arguments are simply ignored.
Try changing the first couple of lines of this function from
function myFunction() {
var xmlDoc = XMLHttpRequest.responseXML;
to
function myFunction(result) {
var xmlDoc = result.responseXML;
This allows myFunction to receive the xmlhttp instance and pull the response XML out of it.
Secondly, at the end of the function you write:
document.getElementById("students") = table;
Your variable table contains an HTML string representing the contents of a table. However, you can't set an element to an HTML string. What you instead want to do is to assign this HTML string to the inner HTML of this element, using the innerHTML property of the element:
document.getElementById("students").innerHTML = table;
Finally, the XML document you include in your question isn't well-formed, in that the ID attribute of the root element uses smart quotes (”) to surround the value when it should use neutral quotes (") instead. If the XML isn't well-formed, the responseXML property of result will be null.
I made these changes to your code and it worked, in that I could load up the XML and have the table filled out with the data in the XML file.
Related
I'm using Ajax/jQuery to pull in some content from an RSS feed, but it seems to be failing to read the content of an XML node with the name 'link'.
Here's a simplified version of the XML:
<?xml version="1.0" encoding="UTF-8"?>
<channel>
<item>
<title>Title one</title>
<link>https://example.com/</link>
<pubDate>Mon, 12 Feb 2019</pubDate>
</item>
<item>...</item>
<item>...</item>
</channel>
</xml>
And the code I'm using:
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
$('item', this.responseText).each(function(){
var thisPostData = {};
thisPostData.title = $(this).find('title').text();
thisPostData.link = $(this).find('link').text();
thisPostData.date = $(this).find('pubDate').text();
posts.push(thisPostData);
});
console.log(posts);
}
};
var posts = [];
xhttp.open('GET', 'https://example.com/rssfeed/', true);
xhttp.send();
You'll see I'm trying to add each 'item' to an object, and storing them inside the 'posts' array. 'Title' and 'pubDate' are stored fine but 'link' isn't.
The actual RSS feed in question contains a huge amount of extra data, all of which I can read except the 'link' nodes. Any suggestions why nodes called 'link' would act differently from all the others?
The problem is because you're attempting to parse XML as HTML. The <link> object in HTML is an inline element, not a block level one, so it has no textContent property for jQuery to read, hence the output is empty.
To fix this first read the XML using $.parseXML(), then put it in a jQuery object which you can traverse.
There's also a couple of things to note. Firstly you will need to remove the </xml> node at the end of the XML output as it's invalid and will cause an error when run through $.parseXML. Secondly you can use map() to build an array instead of manually calling push() on an array, and you can just return the object definition directly from that. Try this:
var responseText = '<?xml version="1.0" encoding="UTF-8"?><channel><item><title>Title one</title><link>https://example.com/</link><pubDate>Mon, 12 Feb 2019</pubDate></item><item><title>Title two</title><link>https://foo.com/</link><pubDate>Tue, 13 Feb 2019</pubDate></item></channel>';
var xmlDoc = $.parseXML(responseText)
var posts = $('item', xmlDoc).map(function() {
var $item = $(this);
return {
title: $item.find('title').text(),
link: $item.find('link').text(),
date: $item.find('pubDate').text()
};
}).get();
console.log(posts);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Lastly, you're using a rather odd mix of JS and jQuery. I'd suggest going with one or the other. As such, here's a full jQuery implementation with the AJAX request included too:
$.ajax({
url: 'https://example.com/rssfeed/',
success: function(responseText) {
var xmlDoc = $.parseXML(responseText)
var posts = $('item', xmlDoc).map(function() {
var $item = $(this);
return {
title: $item.find('title').text(),
link: $item.find('link').text(),
date: $item.find('pubDate').text()
};
}).get();
// work with posts here...
}
});
This is my html code. Here I declared one variable.
<script src="index.js">
var str = {{:stringVar:}};
</script>
This is my JavaScript file content. Here if my condition satisfies my HTML file variable have to get my javascript file variable and it must be replaced.
var hello='gettingvalue from browser'
if(hello ='master'){
var changestr ='new asp key for mas';
}
else{
var changestr ='new asp key for dev'
}
How can I get my HTML file variable into js file?
you can use ajax to read your HTML file.
first read your HTML file then replace your new variable then write it into html file
Here I gave code to read html file inside JS file and replace that variable
if(true){
var aspkey = 'key for master';
var ajax = new ej.base.Ajax('./src/template.html', 'GET', true);
ajax.send().then(function (result) {
var f = result;
var newstr = f.replace(/{{:stringVar:}}/, aspkey)
});
}
else{
var aspkey = 'key for dev';
var ajax = new ej.base.Ajax('./src/template.html', 'GET', true);
ajax.send().then(function (result) {
var f = result;
var newstr = f.replace(/{{:stringVar:}}/, aspkey)
});
}
Finally you have to write this into your HTML file
You could get HTML file content using jquery ajax call as follows
$.get("PATH_TO_HTML_FILE", function(fileText){
console.log(fileText)
});
This is related to another question, but is not a duplicate.
It deals with a proposed solution that I have reached an impasse.
I have the following code that reads an XML, makes changes, opens a window, and writes the XML into the document. The problem is that the content is not rendered as XML.
Any way to set a content type, etc, to have the browser handle the content as XML?
<script>
var wxml;
var xDoc;
var xDevices, xInputs;
var xDevice, xInput;
function fSetXmlAInput(iDevice, iNode, nodeNewVal) {
xInput = xInputs[iNode];
xValue = xInput.getElementsByTagName("value")[0];
// change node value:
// console.log("nodeVal: " + xValue.firstChild.nodeValue);
xValue.firstChild.nodeValue = nodeNewVal;
// console.log("newVal: " + xValue.firstChild.nodeValue);
}
function fSetXmlDevice(iDevice) {
xDevice = xDevices[iDevice];
xInputs = xDevice.getElementsByTagName("input");
fSetXmlAInput(iDevice, 0, "22");
fSetXmlAInput(iDevice, 1, "33");
}
function alternativeLoadXML3() {
// load xml file
if (window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
} else { // IE 5/6
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.open("GET", "my_template.xml", false);
xhttp.send();
xDoc = xhttp.responseXML;
xDevices = xDoc.getElementsByTagName("device");
fSetXmlDevice(1);
var xmlText = serializeXmlNode(xDoc);
var newWindow = window.open("my_template.xml", "Test", "width=300,height=300,scrollbars=1,resizable=1");
newWindow.document.open();
newWindow.document.write(xmlText);
newWindow.document.close()
};
</script>
Below the XML as well:
<?xml version="1.0" encoding="utf-8"?>
<myXmlRoot>
<device>
<input><name>"name 1"</name><value>{replaceMe!}</value></input>
<input><name>"name 2"</name><value>{replaceMe!}</value></input>
</device>
<device>
<input><name>"name 1"</name><value>{replaceMe!}</value></input>
<input><name>"name 2"</name><value>{replaceMe!}</value></input>
</device>
<device>
<input><name>"name 1"</name><value>{replaceMe!}</value></input>
<input><name>"name 2"</name><value>{replaceMe!}</value></input>
</device>
</myXmlRoot>
Any way to force the browser to render content in new window as XML...or does using document.open and document.write mean code is rendered as HTML?
Related: Change XML content using JavaScript, missing refresh
Use dataURI to write xml into new window is very easy.
window.open('data:text/xml,'+encodeURIComponent(xmlText),
"Test", "width=300,height=300,scrollbars=1,resizable=1");
Both document.open and document.write are used to write HTML or Javascript to a document. This goes back to the DOM Level 2 Specification of document.open, which assumes that the document is opened in order to write unparsed HTML.
Instead of using document.open and document.write, I would instead suggest dymanically adding elements using the XML DOM as in sampleElement.appendChild(XMLnode)
A similar question can also be found here: how to display xml in javascript?
I need some code for parsing XML from a url in javascript. I tried following code:
Source:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
<html>
<head><title>Employee Data</title>
<script>
// This function loads the XML document from the specified URL, and when
// it is fully loaded, passes that document and the url to the specified
// handler function. This function works with any XML document
function loadXML(url, handler) {
// Use the standard DOM Level 2 technique, if it is supported
if (document.implementation && document.implementation.createDocument) {
// Create a new Document object
var xmldoc = document.implementation.createDocument("", "", null);
// Specify what should happen when it finishes loading
xmldoc.onload = function() { handler(xmldoc, url); }
// And tell it what URL to load
xmldoc.load(url);
}
// Otherwise use Microsoft's proprietary API for Internet Explorer
else if (window.ActiveXObject) {
var xmldoc = new ActiveXObject("Microsoft.XMLDOM"); // Create doc.
xmldoc.onreadystatechange = function() { // Specify onload
if (xmldoc.readyState == 4) handler(xmldoc, url);
}
xmldoc.load(url); // Start loading!
}
}
// This function builds an HTML table of employees from data it reads from
// the XML document it is passed.
function makeTable(xmldoc, url) {
// Create a <table> object and insert it into the document.
var table = document.createElement("table");
table.setAttribute("border", "1");
document.body.appendChild(table);
// Use convenience methods of HTMLTableElement and related interfaces
// to define a table caption and a header that gives a name to each column.
var caption = "Employee Data from " + url;
table.createCaption().appendChild(document.createTextNode(caption));
var header = table.createTHead();
var headerrow = header.insertRow(0);
headerrow.insertCell(0).appendChild(document.createTextNode("Name"));
headerrow.insertCell(1).appendChild(document.createTextNode("Address"));
headerrow.insertCell(2).appendChild(document.createTextNode("State"));
// Now find all <employee> elements in our xmldoc document
var employees = xmldoc.getElementsByTagName("item");
// Loop through these employee elements
for(var i = 0; i < employees.length; i++) {
// For each employee, get name, job, and salary data using standard DOM
// methods. The name comes from an attribute. The other values are
// in Text nodes within <job> and <salary> tags.
var e = employees[i];
var name = e.getAttribute("name");
var job = e.getElementsByTagName("address")[0].firstChild.data;
var salary = e.getElementsByTagName("state")[0].firstChild.data;
alert(name);
// Now that we have the employee data, use methods of the table to
// create a new row and then use the methods of the row to create
// new cells containing the data as text nodes.
var row = table.insertRow(i+1);
row.insertCell(0).appendChild(document.createTextNode(name));
row.insertCell(1).appendChild(document.createTextNode(job));
row.insertCell(2).appendChild(document.createTextNode(salary));
}
}
</script>
</head>
<!--
The body of the document contains no static text; everything is dynamically
generated by the makeTable() function above.
The onload event handler starts things off by calling loadXML() to load the XML data file. Note the use of location.search to encode the name of the xml file in the query string. Load this HTML file with a URL like this: DisplayEmployeeData.html?data.xml
-->
<body onload="loadXML(url, makeTable)">
</body>
</html>
I have what should be a relatively simple task that's frankly got me stumped. I've researched it until my brain is fried, and now I'm punting, and asking you guys for help.
Here's the scenario:
I have an ASPX page (Q2.aspx) that is decorated with the WebService,
WebServiceBinding, and ScriptService attributes.
That page contains a method, GetAllContacts, that is decorated with the WebMethod
attribute and returns a string containing JSON data. (For what it's worth, the page
itself contains no other controls or functionality.)
I have an HTML page that contains JavaScript which uses the XmlHttpRequest
object to invoke the GetAllContacts WebMethod on the ASPX page and transform
the JSON data into an HTML table.
I have verified that my Web.Config file contains the appropriate protocol handlers
for HttpGet and HttpPut in the WebServices section under System.Web.webServices.
I have verified that my Web.Config file contains the ScriptModule entry under the
System.webServer.modules section, and that it matches the appropriate documentation.
However, when I view the HTML page in a browser, the following occur:
The web request goes through, but the results are for the unprocessed HTML from the ASPX page.
The GetAllContacts method is never invoked, as evidenced by setting a breakpoint in its code.
The code to invoke the Web service, however, is invoked, and the JavaScript callback
function that is invoked upon request completion is properly invoked.
It appears that the JavaScript code is largely set up correctly, but for some reason that is completely escaping me at this point, the HTML page will simply not execute the WebMethod on the ASPX page, and simply returns the page as though it were a plain HTML GET request. Clearly, an HTML document can't be evaluated by JavaScript's eval function, which brings me to my problem. (Also note that the JSON data appears nowhere in the HTML that's returned.)
I am, frankly, baffled. I've looked at dozens of Microsoft articles, StackOverflow posts, CodeProject articles, and who knows what else. My code looks like it's okay. But I know better. I'm missing something simple, stupid, and obvious. I just need someone to point it out to me.
Below you'll find the ASPX page code and the HTML code, in the hope that they'll shed some light.
ASPX Code
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Q2.aspx.cs" Inherits="Satuit.Q2" enablesessionstate="False" %>
<html>
<body>
<form runat="server" id="frmMain"/>
</body>
</html>
-- Codebehind
using System.IO;
using System.Web;
using System.Web.Script.Services;
using System.Web.Services;
using System.Web.UI;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
namespace Satuit
{
[WebService(Namespace="http://tempuri.org")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public partial class Q2 : Page
{
[WebMethod]
public static string GetAllContacts()
{
return LoadJsonData();
}
private static string LoadJsonData()
{
using (var stringWriter = new StringWriter())
{
string xmlUri = HttpContext.Current.Server.MapPath("\\XmlData\\Contacts.xml");
string xslUri = HttpContext.Current.Server.MapPath("\\XmlData\\Q2.xsl");
using (var xmlTextReader = new XmlTextReader(xmlUri))
{
var xpathDocument = new XPathDocument(xmlTextReader);
var xslTransform = new XslCompiledTransform();
xslTransform.Load(xslUri);
xslTransform.Transform(xpathDocument, null, stringWriter);
return stringWriter.ToString();
}
}
}
}
}
HTML Code
var objectData; // Receives the objectified results of the JSON request.
var xmlhttp;
if(window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
xmlhttp.open("GET", "/Q2.aspx/GetAllContacts", true);
xmlhttp.setRequestHeader("content-type", "application/x-www-form-urlencoded");
xmlhttp.onreadystatechange = function ()
{
if (xmlhttp.readyState == 4)
{
if (xmlhttp.status == 200)
{
var jsonResultBuffer = xmlhttp.responseText;
objectData = eval(jsonResultBuffer);
DisplayTable();
}
}
};
xmlhttp.send(null);
function DisplayTable()
{
var sHtml = "";
sHtml = "<table><tr><th>ID</th><th>First</th><th>Last</th><th>Address</th></tr>";
for(i = 0; i < objectData.length; i++)
{
sHtml += "<tr>";
sHtml += "<td>" + objectData.ID;
sHtml += "<td>" + objectData.firstName + "</td>";
sHtml += "<td>" + objectData.lastName + "</td>";
sHtml += "<td>" + objectData.address + "</td>";
sHtml += "</tr>"
}
sHtml += "</table>"
document.getElementById("divTable").innerHTML = sHtml;
}
</script>
Dev Environment Details
Vista Ultimate SP 2
Visual Studio 2008
.NET Framework 3.5
Solution has not yet been deployed, so it's running in the "local Web server"
provided by Visual Studio. (Makes me wonder if I shouldn't just deploy IIS
under Vista.)
Note that the ASPX page containing the WebMethod and the HTML page reside within
the same solution.
I think we need to call web method with POST request
try changing this part of code
xmlhttp.open("POST", "/Q2.aspx/GetAllContacts", true);
xmlhttp.setRequestHeader("content-type", "application/json");
xmlhttp.setRequestHeader("Accept", "application/json");
xmlhttp.onreadystatechange = function ()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
var jsonResultBuffer = JSON.parse(xmlhttp.responseText);
objectData = jsonResultBuffer.d;
DisplayTable();
}
};
Response is returned in JSON format with "d" as the key in xmlhttp.responseText
Pls try the following using jquery to see the web service is accessible or not.
$.ajax({
type: "POST",
url: "Q2.aspx/GetAllContacts",
data: "",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(response) {
alert("success");
},
error: function(response, aa) {
alert("fail");
}
});
Thurein