0

I need to write my JavaScript function that will iterate over an input type file to get the content of multiple XML files (one by one) and concatenate it in such a way that first line of content in all files (except first file) is removed and rest content is in one single variable or JavaScript array or whatever works with browser. I have spent days researching all over Google but could not get it to work so, finally posting here.

function call(){
    var myFile = $('#xmlFileUploaded').get(0);
    var xml=new Array();
    for (let i = 0; i < myFile.files.length; i++) {
        (function(file){
            let reader = new FileReader();  
            reader.onload = function() {
                xml.push(reader.result);
            }
            reader.readAsText(file);
        })(myFile.files[i]);
    }
        console.log(xml);
        for(let x=0;x<xml.length;x++)
            console.log(xml[x]);
}

After spending hours and days on this I have created above code. I run it and select 3 XML files. console.log in Chrome is showing empty array []. When I click on the little triangle to see details it shows correct array length i.e. 3 and content of the 3 files. Now starts the confusing statement, if I iterate over this array it gives me nothing.

chrome console.log output

Sample XML files:

one.xml:

<myroot>
<tag1>value1</tag1>
<tag2>value2</tag2>
</myroot>

two.xml

<myroot>
<tag1>value3</tag1>
<tag2>value4</tag2>
</myroot>

three.xml

<myroot>
<tag1>value5</tag1>
<tag2>value6</tag2>
</myroot>

Desired Output:

<myroot>
<tag1>value1</tag1>
<tag2>value2</tag2>
<tag1>value3</tag1>
<tag2>value4</tag2>
<tag1>value5</tag1>
<tag2>value6</tag2>
</myroot>
Cerbrus
  • 70,800
  • 18
  • 132
  • 147
ManWarrior
  • 35
  • 1
  • 2
  • 9
  • 1
    Okay you'vre written the code that loads the files and it works. What's blocking you from there? What did you try? – spectras Sep 20 '17 at 08:15
  • Appreciate quick response. It is not working. If I iterate over this xml array it shows nothing. The console.log statement at the end of call() function gives me nothing. – ManWarrior Sep 20 '17 at 08:18
  • The array you built is just a plain array, with 3 strings, each string holding the whole content of one of your files. If you want to parse them into a DOM tree, you have to [do it explicitly](https://developer.mozilla.org/en-US/docs/Web/Guide/Parsing_and_serializing_XML). Alternatively, if you know for sure its text layout, you may split it into lines and manipulate them. For instance, dropping the first and last line could work if you are certain root tags will always be on those line, alone. – spectras Sep 20 '17 at 08:23
  • Parsing part or splitting into lines I can do once it is accessible. First, I need to be able to access it. If I try console.log(xml[0]); it shows undefined. But if I try console.log(xml); it is showing array. This looks strange to me. – ManWarrior Sep 20 '17 at 08:33
  • FileReader's methods are asynchronous, you need to wait for it to finish before using their results. Now, for your next step, consider using an [DOMParser](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser) to work with your XML markup, any other text based approach may fail. – Kaiido Sep 20 '17 at 08:47
  • I got your point Kaiido. But this does not work even for plain text files. If we leave xml aside. Is there a way to concatenate plain text files content using filereader? – ManWarrior Sep 20 '17 at 09:23
  • @ManWarrior, yes you can concatenate text files, quite easily, but it's not what you want (just for reference, you would do `new Blob([file1, file2])` or even `new Blob(input.files)` to get the concatenation). But in your case, this will lead you to an invalid xml file. Instead, you should keep your approach of iterating through the files, keep the first one as the host, parse its content as XML, parse all others as XML too, and grab their content that you'll append in the main's parsed document, before getting back the markup of this main element: https://jsfiddle.net/4hba4ba9/ – Kaiido Sep 20 '17 at 14:14
  • @Kaiido: This is easier than I thought. I never thought of using Promises but I guess I need to. I thought of using text based approach and just slice the content of all files except first then returning it. Will try this too with Promises. Thank you for sharing this knowledge. – ManWarrior Sep 21 '17 at 08:26

0 Answers0