javascriptxml

Unexpected 'xmlns' attribute in serialized XML


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.

screenshot of web app

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>

My reference for handling XML in JavaScript


Solution

  • 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');