0

I want to use xml2js to build XML file from array of objects. Is there a way to do it?

This doen't work because xml2js.Builder() expects a single object.

export const buildXML = (data: any[]) => {
  const builder = new xml2js.Builder();
  return builder.buildObject(data)
}

This returns array of XMLs but I need a single one:

export const buildXML = (data: any[]) => {
  const builder = new xml2js.Builder();
  return data.map(obj => builder.buildObject(obj))
}

The resulted XML should be used in this function

export const downloadFile = (data: any[], fileName = 'generator_result', fileFormat: any) => {
  let parsedData: any
  const FILE_TYPE = fileFormat === 'xml' ? XML_TYPE : EXCEL_TYPE;
  if (fileFormat === 'xml') {
    parsedData = buildXML(data);
  } else {
    parsedData = downloadAsExcel(data, fileFormat)
  }
  const fileData = new Blob([parsedData], {type: FILE_TYPE});
  saveAs(fileData, fileName + '.' + fileFormat);
}

UPD If I do this then nothing happens...I mean no console.log(x)...this means that something is wrong in line const x = builder.buildObject(data) isn't it?

export const buildXML = (data: any[]) => {
  const builder = new xml2js.Builder();
  const x = builder.buildObject(data)
  console.log('x:', x)
  return x
}
qweezz
  • 508
  • 4
  • 24
  • What's the result you're expecting? XML needs a root element. So you'll need at least a parent object containing your array. – lbsn Dec 28 '21 at 10:30
  • @lbsn my task is to get a single XML file which contains all the data from array of objects. It's not a problem if XML will have some other root element (no strict rules about XML output structure)....the most important part is to have all data inside it. Unfortunattely I don't know how to do this – qweezz Dec 28 '21 at 10:40

1 Answers1

1

You can just pass your array to the builder:

const data = [{ item: '1' }, { item: '2' }, { item: '3' }];
const buildXML = (data) => {
  const builder = new xml2js.Builder();
  return builder.buildObject(data);
};
const doc = buildXML(data);

Since XML must have a root element xml2js will add it for you producing this result:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
  <item>1</item>
  <item>2</item>
  <item>3</item>
</root>

If you'd like to have more control about the root element just wrap your array in a parent object with a single property (property's name will become the root element):

const data = {data: [{ item: '1' }, { item: '2' }, { item: '3' }]};
const buildXML = (data) => {
  const builder = new xml2js.Builder();
    return builder.buildObject(data);
  };
const doc = buildXML(data);

Result:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<data>
  <item>1</item>
  <item>2</item>
  <item>3</item>
</data>
lbsn
  • 2,322
  • 1
  • 11
  • 19
  • Actually this doesn't work for me. I added UPD comment in initial post with explanations – qweezz Dec 28 '21 at 11:01
  • That should definitely work: [stackblitz](https://stackblitz.com/edit/js-fanm7g). Can you share more code or put together a working example with your issue? – lbsn Dec 28 '21 at 11:07
  • Thank you very much. Everything works fine. I tested on localhost with data mocked...and nothing happened as I mentioned. But I uploaded project to dev server with real data - everything started to work as needed. – qweezz Dec 28 '21 at 11:52