I am developing an Adobe UXP plugin for Adobe Photoshop, and my requirement is to make an API call and parse the XML response. While attempting to parse the XML response, I discovered that there is no method to read the response stream and parse it to XML.
When using the DOM Parser to read an XML file, I found that our UXP does not support the DOM Parser. Additionally, since my plugin is a vanilla JavaScript project, I am unable to load libraries like xml2js to parse the XML object…
I have tried creating a div element from JavaScript, assign the XML string as its innerHTML, and then use the XML object
// Create a new div element
const div = document.createElement('div');
// Set the XML string as the div's innerHTML
const xmlString = `
<root>
<person>
<name>John Doe</name>
<age>30</age>
</person>
<person>
<name>Jane Doe</name>
<age>25</age>
</person>
</root>
`;
div.innerHTML = xmlString;
// Get the XML object from the div
const xmlObject = div.firstChild;
// Use the XML object
console.log(xmlObject); // Output: <root>...</root>
// Access specific elements
const persons = xmlObject.getElementsByTagName('person');
console.log(persons[0].getElementsByTagName('name')[0].textContent);
Unfortunately, this approach did not work. I would appreciate it if someone who has faced a similar challenge could assist me with this issue.
what if You add the div in a hidden state to the DOM and parse it from there?
I know, this is not the most elegant/performant way, but as You mentioned, DOMParser is not available.
Something like this maybe:
// Set the XML string as the div's innerHTML
let xmlString = `
<root>
<person>
<name>John Doe</name>
<age>30</age>
</person>
<person>
<name>Jane Doe</name>
<age>25</age>
</person>
<person>
<name>Jane Doe</name>
<age>25</age>
</person>
</root>
`;
// Create a new div element
const div = document.createElement('div');
div.id = 'tmp-xml-string';
div.style.cssText = 'display: none; position: fixed; top: -9999px; left: -9999px;';
div.innerHTML = xmlString;
document.body.appendChild(div);
const xmlEl = document.getElementById(div.id)
// Recursively parse `xmlEl`.
const parse = (nodeEls = xmlEl.children) => {
if(!xmlEl) return console.warn('xmlEl not found');
for (let i = 0; i < nodeEls.length; i++) {
const childEl = nodeEls[i];
// Node has children, call `parse` again with its children.
if(childEl.children.length) {
parse(childEl.children);
continue;
}
console.log(childEl.nodeName + '\n', childEl.innerText)
}
// Remove xmlEl from DOM
xmlEl.remove();
}
// Parse from DOM
// (maybe wrap in a `setTimeout(_ => parse())` to ensure that
// `xmlEl` is ready in DOM)
parse()
This method of course doesn’t work, if Your XML string contains self-closing tags.