Unable to parse XML in Adobe UXP

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.

https://developer.adobe.com/premiere-pro/uxp/uxp-api/reference-js/Global%20Members/Data%20Transfers/Response/

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.

Hey @skathuria,

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.

1 Like

PS: I just quickly tested the fast-xml-parser library, which works in UXP.
It even parses self-closing tags.

import { XMLParser } from "fast-xml-parser";

const parser = new XMLParser();
let jObj = parser.parse(xmlString);
console.log('jObj', jObj)
2 Likes