I am trying to read the content of the XML file. Probably this is basic JS stuff, but I seem can't make it work.
I am using Chrome's experimental Native File System API to read folders in folder:
const opts = {type: 'open-directory'};
handle = await window.chooseFileSystemEntries(opts);
const entries = await handle.getEntries();
...
Then, later on in the code I am entering one of the folders from the main directory and trying to read the file in it. The file system strucure is like this:
Directory > subdirectory > file
and the second part of the code looks like this:
var subdirHandle = await handle.getDirectory(oneOfTheFolders);
var xmlFile = await subdirHandle.getFile('subject.xml');
xmlDoc = domParser.parseFromString(xmlFile, "text/xml");
parsedNumber = document.evaluate(myXpathFce('nodeInXML'), xmlDoc, null, XPathResult.ANY_TYPE, null).iterateNext();
if(parsedNumber.childNodes.length >0){
...
I believe the issue is here var xmlFile = await subdirHandle.getFile('subject.xml'); with the file reading. If I loaded the file straight from the Input and used FileReader(), I was able to get the content and parse it, but with the 'directory' approach I am getting null (for the evaluated document) like this Uncaught (in promise) TypeError: Cannot read property 'childNodes' of null
Edit here is what I get in console for the xmlFile variable. I just need to get the content (XML in text format) from this
I noticed you're saving the File object in the xmlFile variable and passing it directly into the parseFromString method.
You cannot parse a document object from a File object directly. You should first read the string from the File object using a FileReader. You can read the string from a File object with the await keyword using the readFileAsync function below:
function readFileAsync(file) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = reject;
reader.readAsText(file);
})
}
var file = await handle.getFile();
var text = await readFileAsync(file);
var xmlDoc = domParser.parseFromString(text, "text/xml");
For obtaining the contents of a FileSystemFileHandle, call getFile(), which returns a File object, which contains a blob. To get the data from the blob, call one of its methods (slice(), stream(), text(), arrayBuffer()).
Related
In my Vuejs front-end, there is a file upload button. When user selected the file Vuejs triggers the #change event.I have used the file reader and I have imported the Cryptojs libraries which I have downloaded as node modules(in npm).
import cryptoJs from '../../node_modules/crypto-js'
import md5 from '../../node_modules/crypto-js/md5'
My html code for file upload button as follows:
<input type="file" ref="uploadedfile" name="file1" id="file1" #change="handleFileUpload">
File reader code inside the #change function:
handleFileUpload(e){
const filesToRead = e.target.files;
//getting the first file from the files array
let file1 = filesToRead[0];
const fileReader = new FileReader();
fileReader.addEventListener('loadend', (evt) => {
if (evt.target.readyState == FileReader.DONE) {
file1 = fileReader.result;
const encryptedvalue = md5(cryptoJs.enc.Latin1.parse(file1)).toString();
console.log("MD5 value is :");
console.log(encryptedvalue);
}
});
}
But always I get the same md5 value although I selected different files.
In the file object array, I can see all the file related data also when I inspect through the Chrome developer tool's console.(If I console log as follows)
console.log(file1);
The posted code lacks the call that loads the data. This is probably just a copy/paste error. Since the data is parsed with the Latin1 (aka ISO 8859-1) encoder, FileReader.readAsBinaryString() is an appropriate method, e.g.:
handleFileUpload(e) {
const filesToRead = e.target.files;
let file1 = filesToRead[0];
const fileReader = new FileReader();
fileReader.addEventListener('loadend', (evt) => {
if (evt.target.readyState == FileReader.DONE) {
file1 = fileReader.result;
const encryptedvalue = md5(cryptoJs.enc.Latin1.parse(file1)).toString();
console.log("MD5 value is :");
console.log(encryptedvalue);
}
});
fileReader.readAsBinaryString(file1); // missing in the posted code
}
However, I cannot reproduce the problem with this code, neither locally nor online https://codesandbox.io/s/brave-fast-cx9gz (if in the online case the error message C is undefined is displayed, this can generally be eliminated by commenting out and in the two CryptoJS import lines in components/Repro - no idea why this happens).
However, I can reproduce the issue when the data is loaded with FileReader.readAsArrayBuffer(). If the ArrayBuffer is then parsed with the Latin1 encoder (as in the posted code), which is incompatible for this, then for different files always the same hash results. The result is correct again if the WordArray is created directly from the ArrayBuffer with:
const encryptedvalue = md5(cryptoJs.lib.WordArray.create(file1)).toString();
I am searching for a JavaScript library, which can read .doc - and .docx - files. The focus is only on the text content. I am not interested in pictures, formulas or other special structures in MS-Word file.
It would be great if the library works with to JavaScript FileReader as shown in the code below.
function readExcel(currfile) {
var reader = new FileReader();
reader.onload = (function (_file) {
return function (e) {
//here should the magic happen
};
})(currfile);
reader.onabort = function (e) {
alert('File read canceled');
};
reader.readAsBinaryString(currfile);
}
I searched through the internet, but I could not get what I was looking for.
You can use docxtemplater for this (even if normally, it is used for templating, it can also just get the text of the document) :
var zip = new JSZip(content);
var doc=new Docxtemplater().loadZip(zip)
var text= doc.getFullText();
console.log(text);
See the Doc for installation information (I'm the maintainer of this project)
However, it only handles docx, not doc
now you can extract the text content from doc/docx without installing external dependencies.
You can use the node library called any-text
Currently, it supports a number of file extensions like PDF, XLSX, XLS, CSV etc
Usage is very simple:
Install the library as a dependency (/dev-dependency)
npm i -D any-text
Make use of the getText method to read the text content
var reader = require('any-text');
reader.getText(`path-to-file`).then(function (data) {
console.log(data);
});
You can also use the async/await notation
var reader = require('any-text');
const text = await reader.getText(`path-to-file`);
console.log(text);
Sample Test
var reader = require('any-text');
const chai = require('chai');
const expect = chai.expect;
describe('file reader checks', () => {
it('check docx file content', async () => {
expect(
await reader.getText(`${process.cwd()}/test/files/dummy.doc`)
).to.contains('Lorem ipsum');
});
});
I hope it will help!
Properties of files received from an <input type="file"> are read-only.
For example, the following attempt to re-write file.name would either fail silently or throw TypeError: Cannot assign to read only property 'name' of object '#<File>'.
<input onchange="onchange" type="file">
onchange = (event) => {
const file = event.target.files[0];
file.name = 'foo';
}
Attempting to create a copy via Object.assign({}, file) fails (creates an empty object).
So how does one clone a File object?
My solution lay in the File constructor:
https://developer.mozilla.org/en-US/docs/Web/API/File#Implementation_notes
Which itself is an extension of Blob:
https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob
let file = event.target.files[0];
if (this.props.distro) {
const name = 'new-name-here' + // Concat with file extension.
file.name.substring(file.name.lastIndexOf('.'));
// Instantiate copy of file, giving it new name.
file = new File([file], name, { type: file.type });
}
Note the first argument to File() must be an array, not simply the original file.
You can use FormData.prototype.append(), which also converts a Blob to a File object.
let file = event.target.files[0];
let data = new FormData();
data.append("file", file, file.name);
let _file = data.get("file");
A more cross browser solution
The accepted answer works for me too in modern browsers, but unfortunately it does not work in IE11, since IE11 does not support the File constructor.
However, IE11 does support the Blob constructor so it can be used as an alternative.
For example:
var newFile = new Blob([originalFile], {type: originalFile.type});
newFile.name = 'copy-of-'+originalFile.name;
newFile.lastModifiedDate = originalFile.lastModifiedDate;
Source: MSDN - How to create a file instannce using HTML 5 file API?
I'm trying to upload an image that the user gives me via copy and paste and I am wondering how to upload such data to Filepicker/Filestack.
My code so far:
var pasteHandler = function (event) {
// turned out to be needed because of jquery
if (event.originalEvent !== undefined) {
event = event.originalEvent;
}
var clipboardData = event.clipboardData;
var items = clipboardData ? clipboardData.items : [];
_.each(items, function (clipboardItem) {
if (clipboardItem.kind == 'file' && clipboardItem.type.indexOf('image/') !== -1) {
var blob = clipboardItem.getAsFile();
var reader = new FileReader();
reader.onload = function (event) {
var fileUrl = event.target.result;
/* I get a fileUrl here that I can assign to an img element and see the result */
filepicker.store(
/*what should I send here?*/,
function(Blob){
console.log(JSON.stringify(Blob));
}
);
};
reader.readAsDataURL(blob)
}
});
};
Can somebody tell me what to send to filepicker/filestack there?
Everything I tried so far resulted in this error:
"Uncaught FilepickerException: Cannot store given input: [object DataTransferItem]. Not a string, file input, DOM File, or FPFile object."
Apparently I can't use an input field with the type "file" as there is no way to set the value of the input field to be the pasted file.
What is a DOM File here? I tried using new File(['testData'], 'test.txt') without success. I get the following error:
"FPError 122: The Remote URL could not be reached. For help, see https://developers.filepicker.io/answers/jsErrors/122"
Which makes me think maybe filepicker.store() is not the right choice for this task as it seems to be expecting an url which I don't have yet (I mean that's what I'm trying to do, right? Getting an url for the uploaded file FROM filepicker).
In the Filepicker API itself I only find examples that use another filepicker method before and therefore already have a valid url for the file.
Thanks in advance,
Jesse :)
I am new to java and javascript programing.
I was able to write a piece of code in java to access a particular URL and download the wav file from that URL (this url returns a wav file).
url = new URL('url name');
input = url.openStream();
output = new FileOutputStream (wavfile);
byte[] buffer = new byte[500];
int bytesRead = 0;
while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
output.write(buffer, 0, bytesRead);
}
output.close();
I do not want to do this in Java and want to be able to do it in Javascript. The main attempt is to use javascript and get the wav file and play it on a HTML5 enabled browser.
I eventually want to put it on an android platform, so do not prefer to use ajax or jquery.
Please suggest how this can be done in javascript.
Thanks,
axs
You couldn't use JavaScript to read files but HTML5 has a File API, take a look at:
http://dev.w3.org/2006/webapi/FileAPI/
READING FILES IN JAVASCRIPT USING THE FILE APIS
export async function loadWavFromUrl(audioContext, url) {
const response = await fetch(url);
const blob = await response.blob()
const arrayBuffer = await blob.arrayBuffer();
return await audioContext.decodeAudioData(arrayBuffer);
}
I recommend reusing AudioContext instances, which is why there is a param for it. You can call like this:
const ac = new AudioContext();
loadWavFromUrl(audioContext, url).then(audioBuffer => ...do stuff with it...);
The OP is maybe confused about reusing Javascript code in Java/Android. The code will be different.