I'm trying to generate XSPF (XML) in JavaScript, and display the generated code in a <pre>
block on a webpage. This is for a web app that creates music playlists.
This is the JS code I'm currently experimenting with:
const xspfTemplate = `<?xml version="1.0" encoding="UTF-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
<trackList>
</trackList>
</playlist>`;
const parser = new DOMParser();
const serializer = new XMLSerializer();
xspfDoc = parser.parseFromString(xspfTemplate, 'text/xml');
let track = xspfDoc.createElement('track');
let location = xspfDoc.createElement('location');
location.textContent = encodeURIComponent('my album/my music.mp3');
track.append(location);
xspfDoc.querySelector('trackList').append(track);
let xspfString = serializer.serializeToString(xspfDoc);
xspfOutput.append(xspfString);
After investigating with the Firefox debugger, it appears to me that the serialization step is adding an empty xmlns
attribute to the <track>
element.
Actual output:
<?xml version="1.0" encoding="UTF-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
<trackList>
<track xmlns=""><location>my%20album%2Fmy%20music.mp3</location></track></trackList>
</playlist>
Expected output:
<?xml version="1.0" encoding="UTF-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
<trackList>
<track><location>my%20album%2Fmy%20music.mp3</location></track></trackList>
</playlist>
Failing to specify that track
is in the default namespace results in it being placed in no namespace and is causing the undesired xmlns=""
. To correct this, rather than createElement()
use createElementNS()
to place track
and location
elements into the default http://xspf.org/ns/0/
namespace.
Change
let track = xspfDoc.createElement('track');
let location = xspfDoc.createElement('location');
to
const ns = 'http://xspf.org/ns/0/';
const track = xspfDoc.createElementNS(ns, 'track');
const location = xspfDoc.createElementNS(ns, 'location');