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
}
2
  • What's the result you're expecting? XML needs a root element. So you'll need at least a parent object containing your array. Commented Dec 28, 2021 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 Commented Dec 28, 2021 at 10:40

1 Answer 1

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>
Sign up to request clarification or add additional context in comments.

3 Comments

Actually this doesn't work for me. I added UPD comment in initial post with explanations
That should definitely work: stackblitz. Can you share more code or put together a working example with your issue?
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.