I am trying to parse a XML-file using java-script. Actually, I read many tutorials to find out how to parse the data from the XML-file correctly, and I found that I am on the right way.
Concerning the loadXMLDoc(dname) function, I passed the path of the XML-file to loadXMLDoc function as follows:
var dname = "D:\files\files\Schriftsteller.xml";
function loadXMLDoc(dname)
But still the parsing does not give me the desired result, I want to display the name in the following tag
<name>Jane Austin</name>
but the web browser does not display it, I am using Chrome.
Please, (1) Let me know where my mistake is? (2)what extension the parser file should be saved under(.HTML/.js)
Please find below the XML-file and the java-script file
XML file:
<?xml version="1.0" ?>
<Schriftsteller>
<Englischsprache>
<Dichtung>
<fueller>
<name>Jane Austin</name>
<name>Rex Stout</name>
<name>Dashiell Hammett</name>
</fueller>
</Dichtung>
</Englischsprache>
</Schriftsteller>
JavaScript File.html(Parser):
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<link rel="stylesheet" href="readXML.css" type="text/css">
<title>Read First Child</title>
<!-- <xml ID="Schriftsteller" SRC="D:\files\files\Schriftsteller.xml"></xml> -->
<script language="JavaScript">
var dname = "D:\files\files\Schriftsteller.xml";
function loadXMLDoc(dname)
{
var xmlDoc;
if (window.XMLHttpRequest)
{
xmlDoc=new window.XMLHttpRequest();
xmlDoc.open("GET",dname,false);
xmlDoc.send();
return xmlDoc.responseXML;
}
// IE 5 and IE 6
else if (ActiveXObject("Microsoft.XMLDOM"))
{
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async=false;
xmlDoc.load(dname);
return xmlDoc;
}
alert("Error loading document!");
return null;
}
function findWriter()
{
var schriftstellerKnoten, SpracheKnoten;
var FuellerKnoten, DichtungKnoten, Anzeige;
myXML = document.all(dname).XMLDocumentalert(dname);
SchriftstellerKnoten = myXML.documentElement;
SpracheKnoten = SchriftstellerKnoten.firstChild;
DichtungKnoten = SpracheKnoten.firstChild;
FuellerKnoten = DichtungKnoten.firstChild;
NameNode = FuellerKnoten.firstChild;
Anzeige = NameNode.firstChild.nodeValue;
document.write(Anzeige);
}
</script>
</head>
<body onload="loadXMLDoc(dname)">
<span ID="blueBack">Read firstChild</span>
<div>
<form name="show">
<input type=text name="me">
<input type="button" value="Display Writer"
onClick="findWriter()">
</form>
</div>
</body>
First your XML-Document has to be well-formed.
So for every tag you open add another tag to close it (like you do with the name-tag). The closing tag has to be same as the opening, except for a / in the beginning
Also you have to watch the case (well-formed XML is case-sensitive). The tag
<EnglischSprache> is different from <Englischsprache>
Try it like this:
<?xml version="1.0"?>
<Schriftsteller>
<EnglischSprache>
<Dichtung>
<fueller>
<name>Jane Austin</name>
<name>Rex Stout</name>
<name>Dashiell Hammett</name>
</fueller>
</Dichtung>
</EnglischSprache>
</Schriftsteller>
Then in the JS-File, maybe you should try calling the function loadXMLDoc.
Looks like you're just defining it.
Try it like this:
<body onload="loadXMLDoc(dname)">
Better now?
Related
Aim:
The background loop will continuously read and print the file (word.txt)
Pressing one of the buttons will overwrite the value in word.txt
This change will then be read by the background loop and printed
What happens:
The background loop continuously reads and prints the file (word.txt)
Pressing one of the buttons overwrites the value in word.txt
but.... 3. This change isn't reflected in JS until I go on to the "word.txt" file in a different browser and refresh the page. Once this is done, JS starts recognizing it.
Any ideas? Sorry the snippet doesn't work as it has php in
var instanse = false;
var state;
var mes;
var file;
console.log('update.js loaded');
function triggerUpdate(){
console.log('update.js is triggered');
updateChat();
}
//Background Loop
function updateChat(){
var file = 'word.txt';
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file, false);
rawFile.onreadystatechange = function ()
{
if(rawFile.readyState === 4)
{
if(rawFile.status === 200 || rawFile.status == 0)
{
var allText = rawFile.responseText;
console.log(allText);
}
}
}
rawFile.send(null);
setTimeout(updateChat, 1500);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Random Word Generator</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript"></script>
<script language="javascript" src="update.js" type="text/javascript"></script>
</head>
<body onload="triggerUpdate();">
<form action="" method="post">
<input type="submit" name="word"
class="button" value="Button1" id="button1"/>
<input type="submit" name="word"
class="button" value="Button2" id="button2"/>
</form>
<?php
//This function gets called when button is pushed
function postword(){
$fp = fopen('word.txt', 'w');
fwrite($fp, $_POST['word']);
fclose($fp);
}
//When the button is pushed, the function will be called
if (isset($_POST['word'])) {
postword();
return;
}
?>
</body>
</html>
The browser is caching the initial result of the XMLHttpRequest call. The easiest workaround is to fool the cache by appending a random number as a parameter to the url. it will get ignored by the filesystem when looking for the file.
You can add any query variable you want ('v' is popular - sort of stands for version).
There are many ways to get a random number but using the Unix timestamp - Date.now()
- is an easy one that should do the trick in this case.
Change code from:
var file = 'word.txt';
To:
var file = 'word.txt?v=' + Date.now();
This which will create a call to a url like this: word.txt?v=1519211809934
I have the following code:
code.gs:
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('My Menu')
.addItem('Test', 'showTestForm')
.addToUi();
}
function showTestForm() {
var html = HtmlService.createHtmlOutputFromFile('TestForm');
SpreadsheetApp.getUi().showModalDialog(html, 'TEST');
}
function Test(formObject){
Logger.log("TEST")
var a = new Error( "Allready present "+ formObject);
a.error_code = 99;
Logger.log(JSON.stringify(a));
throw a;
}
TestForm.html
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<base target="_top">
<script>
function onFailure(error) {
var keys = Object.keys(error);
alert(JSON.stringify(keys));
alert(JSON.stringify(error.message));
alert(JSON.stringify(error.error_code));
}
function onSuccess() {
alert("Success");
}
</script>
</head>
<body>
<input type="submit" value="Save" onclick="google.script.run.withFailureHandler(onFailure).withSuccessHandler(onSuccess).Test('1')" />
<input type="button" value="Close" onclick="google.script.host.close()" />
</body>
</html>
When I open TestForm from menu and press "Save" I've got following log from Logger:
[18-12-24 23:08:24:765 PST] TEST
[18-12-24 23:08:24:766 PST] {"message":"Allready present 1","error_code":99}
So I see, that error object have properties 'message' and 'error_code'. But in browser I've got following alerts:
["name"]
"Error: Allready present 1"
undefined
So I see, that recived error object has only one empty (i've checked) property "name". But if I but refer to the property "message, I've got string like in original object (but not the same). And it looks like that object haven't poperty "error_code".
What's the matter?
I thought you might like a complete working example as I know this stuff can be quite frustrating.
This a simple example templated HTML file that can be used as a dialog or a webapp. All it does is create a Google Doc file with todays date in the header and footer of each page and it puts the file into the same directory as the spreadsheet which contains the script. That's it. I use the Chrome Browser. I don't even care if my scripts won't run on another browser.
Here's the HTML: (FileName:'docwithdate.html')
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= include('resources') ?>
<?!= include('css') ?>
</head>
<body>
<?!= include('form') ?>
<?!= include('script') ?>
</body>
</html>
The Resources: (FileName: 'resources.html')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
The CSS: (FileName: 'css.html')
<style>
body {background-color:#ffffff;}
input[type="button"]{padding:0 0 2px 0;}
</style>
The Form: (FileName: form.html) This is probably push the templating idea a little far.
<form id="myForm" onsubmit="event.preventDefault();processForm(this);" >
<input type="text" id="txt1" name="filename" />
<input id="btn" type="submit" value="Submit" />
</form>
The Javascript: [FileName: 'script.html')
<script>
function createFile(){
var name=document.getElementById('filename').value;
google.script.run
.withSuccessHandler(function(rObj){
var html='<br />Go To File:' + rObj.filename + '';
$(html).appendTo("body");
})
.createTemplatedGoogleDoc(name);
}
function getInputObject(obj) {//I'm probably doing something wrong here. But this is what I had to do to get the object with the properties that I desired. So if you have another way. Go for it.
var rObj={};
for(var i=0;i<Object.keys(obj).length;i++){
if(obj[i].type=="text"){
rObj[obj[i].name]=obj[i].value;
}
console.log('Object.keys(rObj): %s',Object.keys(rObj).join(', '));
}
return rObj;
}
function processForm(obj){
var fObj=getInputObject(obj);
var name=fObj.filename;
google.script.run
.withSuccessHandler(function(rObj){
document.getElementById("btn").disabled=true;
var html='<br />Go To File:' + rObj.filename + '';
$(html).appendTo("body");
})
.createTemplatedGoogleDoc(name);
}
console.log('My Code');
</script>
The Google Script: (FileName: Code.gs)
function onOpen(){
SpreadsheetApp.getUi().createMenu('My Menu')
.addItem("Open Templated Google Doc", 'showMyDialog')
.addToUi()
}
function createTemplatedGoogleDoc(name){
Logger.log(name);
var doc=DocumentApp.create(name);//Creates a google doc
var fldrs=DriveApp.getFileById(SpreadsheetApp.getActive().getId()).getParents();
while(fldrs.hasNext()){
var fldr=fldrs.next();
if(fldr.getName()=="Create Templated Google Doc App"){
var folder=fldr;
}
}
Drive.Files.update({"parents": [{"id": folder.getId()}]}, doc.getId());//puts doc file into same directory as the spreadsheet that contains the script
doc.addHeader().appendParagraph(Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "E MMM dd, yyyy"));
doc.addFooter().appendParagraph(Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "E MMM dd, yyyy"));
//doc.getBody().getChild(0).removeFromParent();
doc.saveAndClose()
var rObj={url:doc.getUrl(),filename:doc.getName()}
return rObj;
}
function showMyDialog(){
var ui=HtmlService.createTemplateFromFile('docwithdate').evaluate();
SpreadsheetApp.getUi().showModelessDialog(ui, 'My Doc with Date');
}
function doGet(){//if you want a web app this is helpful
return HtmlService.createTemplateFromFile('docwithdate').evaluate();
}
function include(filename){//this is the include that the template uses
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
It's a pretty simple script. I hope it helps you get a start.
In accordance with the proposal of #TheMaster it is necessary to do this:
code.gs
function Test(formObject){
var a = new Error( JSON.stringify({msg:"Allready present "+ formObject,code:99}));
throw a;
}
TestForm.html
// removing "Error: " from message string to get our json back
var json = error.message.replace("Error: ",'')
var msg = JSON.parse(json).msg;
var code = JSON.parse(json).code;
That is, we put json into the attribute message of the Error object, and then, by cutting our json, we parse it and get the necessary values.
This is not exactly the answer to the question, but a good way to solve the problem.
I'm not overly experienced with the aforementioned technologies, but need to resolve the issues i'm experiencing with the POST function.
<!DOCTYPE html>
<html>
<head>
<title>ajax</title>
<meta charset='UTF-8'>
<script src='lib/ajaxget.js'></script>
<script src='lib/ajaxput.js'></script>
</head>
<body>
<h1>blah</h1>
<div>AJAX uploads go here.</div>
<div id="grabphpdiv"> AJAX uploads from PHP go here.</div>
<br>
<textarea id="comment" rows="5" cols="40"></textarea>
<br>
<button id="put">put</button>
<br>
<br>
<button id="get">get</button>
<script src='dyn.js'></script>
</body>
</html>
The JS 'GET' function is working, so here's the POST that doesn't work (no errors in the console) the text file doesn't update though...
function AjaxPut(URL, callback)
{ var ajaxObj = new XMLHttpRequest();
ajaxObj.open("POST", URL, true);
ajaxObj.onreadystatechange = function()
{ if (ajaxObj.status == 200)
if (ajaxObj.readyState == 4)
callback(ajaxObj.responseText);
};
ajaxObj.send("somestuff");
};
And the PHP for the post (though titled PUT here)
<?php
$jothandle = fopen("jots.txt","w");
fwrite($jothandle,$_REQUEST['line']);
Lastly, here's the JavaScript that's entitled 'dyn.js' at the bottom of the HTML. (though for brevity, i've only pasted in the POST section.
var y = document.getElementById("put");
y.addEventListener("click", runapi1);
y.addEventListener("click", grabphp1);
function runapi1()
{ AjaxPut('api/put.php', grabphp1);}
function grabphp1(response)
{ document.getElementById('grabphpdiv').innerHTML = response; }
Any help or pointers would be very much appreciated! thanks!
It looks like you aren't sending a parameter called line from your JS, but you are expecting one in your PHP code. Try sending this instead: line=somestuff e.g.
ajaxObj.send("line=somestuff");
Send POST data using XMLHttpRequest
I also tried using loadXML() of Microsoft, but it doesn't work. It is most likely deprecated. What perceives to be wrong here. Is there any other way to write it?
The HTML code:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>childNode Property</title>
<script type="text/javascript" src="allfeaturetest.js"></script>
</head>
<body>
<h1>childNode Property</h1>
<hr/>
<form name="input">
<input type="button" value="Press me for XML" onclick="return xmlly()"/>
</form>
<div id="pop">
</div>
</body>
</html>
The JavaScript Code:
function xmlly(){
var resul ="";
var dom = new DOMParser();
var xmlDoc = dom.parseFromString("address.xml","application/xml");
var myElem = xmlDoc.getElementsByTagName("address").childNodes;
alert(myElem); //gives me undefined
alert(xmlDoc); //gives me [Object XMLDocument]
document.getElementById("pop").innerHTML = xmlDoc.documentElement.childNodes[0].attributes[0].nodeValue;
}
The XML file :
<address>
<street>Roble Ave</street>
<mtfcc>S1400</mtfcc>
<streetNumber>649</streetNumber>
<lat>37.45127</lat>
<lng>-122.18032</lng>
<distance>0.04</distance>
<postalcode>94025</postalcode>
<placename>Menlo Park</placename>
<adminCode2>081</adminCode2>
<adminName2>San Mateo</adminName2>
<adminCode1>CA</adminCode1>
<adminName1>California</adminName1>
<countryCode>US</countryCode>
</address>
The error shown to me:
Uncaught TypeError: Cannot read property 'nodeValue' of undefined
parseFromString will not load the data from the address.xml file. As the name says, it will only parse an XML doc from a string, like this:
var dom = new DOMParser();
var xmlDoc = dom.parseFromString("<address>test</address>","application/xml");
You'll need a separate XHR (Ajax) request to load the data from that file.
Also, you should be using console.log instead of an alert to debug this. You'll be able to actually see what's in that object (an error message in your case).
If your sole purpose is to read a node, use below functions -
function xmlly()
{
var xmlDoc=loadXMLDoc("address.xml");
var elm = xmlDoc.getElementsByTagName("street")[0]; // tag name you want to read
var node =elm.childNodes[0];
alert(node.nodeValue)
}
function loadXMLDoc(filename)
{
if (window.XMLHttpRequest)
{
xhttp=new XMLHttpRequest();
}
else // code for IE5 and IE6
{
xhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.open("GET",filename,false);
xhttp.send();
return xhttp.responseXML;
}
I am trying to create a javascript quiz, that gets the questions from a xml file. At the moment I am only starting out trying to parse my xml file without any success. Can anyone point me to what I am doing wrong?
<html>
<head>
<title>Test</title>
<script type="text/javascript" src="prototype.js"></script>
</head>
<body>
<div class="spmArr">
</div>
<script type="text/javascript">
var quizXML = '<quiz><Sporsmal tekst="bla bla bla"/><alternativer><tekst>bla</tekst><tekst>bli</tekst><tekst correct="yes">ble</tekst></alternativer><Sporsmal tekst="More blah"/><alternativer><tekst>bla bla</tekst><tekst correct="yes">bli bli</tekst><tekst>ble ble</tekst></alternativer></quiz>'
var quizDOM = $.xmlDOM( quizXML );
quizDOM.find('quiz > Sporsmal').each(function() {
var sporsmalTekst = $(this).attr('tekst');
var qDiv = $("<div />")
.addClass("item")
.addClass("sporsmal")
.appendTo($(".spmArr"));
var sTekst = $("<h2/>")
.html(sporsmalTekst)
.appendTo(qDiv);
});
</script>
</body>
</html>
When I try this in my browser the classes and div are not being created. And the page is just blank. Am i doing something wrong when I intialize the xml?
edited to add prototype.js and close function
Looks like you're forgetting to close your .each call. append ); after the statement for sTekst and your call will parse correctly.