diff --git a/lib/dom.js b/lib/dom.js
index 78ab77091..31eea2a9f 100644
--- a/lib/dom.js
+++ b/lib/dom.js
@@ -1024,9 +1024,13 @@ function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){
if (needNamespaceDefine(node,isHTML, visibleNamespaces)) {
var prefix = node.prefix||'';
var uri = node.namespaceURI;
- var ns = prefix ? ' xmlns:' + prefix : " xmlns";
- buf.push(ns, '="' , uri , '"');
- visibleNamespaces.push({ prefix: prefix, namespace:uri });
+ if (uri) {
+ // Avoid empty namespace value like xmlns:ds=""
+ // Empty namespace URL will we produce an invalid XML document
+ var ns = prefix ? ' xmlns:' + prefix : " xmlns";
+ buf.push(ns, '="' , uri , '"');
+ visibleNamespaces.push({ prefix: prefix, namespace:uri });
+ }
}
if(child || isHTML && !/^(?:meta|link|img|br|hr|input)$/i.test(nodeName)){
diff --git a/test/parse/node.test.js b/test/parse/node.test.js
index 9d7ff5796..6c10dc825 100644
--- a/test/parse/node.test.js
+++ b/test/parse/node.test.js
@@ -87,6 +87,20 @@ describe('XML Node Parse', () => {
})
})
+ it('prefixed without empty namespace', () => {
+ const source = 'test1test2'
+ const { documentElement } = new DOMParser().parseFromString(source)
+
+ expect(documentElement.firstChild.firstChild).toMatchObject({
+ nodeValue: 'test1',
+ })
+ expect(documentElement.lastChild.firstChild).toMatchObject({
+ nodeValue: 'test2',
+ })
+
+ expect(documentElement.toString()).toStrictEqual(source)
+ })
+
it('cdata comment', () => {
const { documentElement } = new DOMParser().parseFromString(
'start ]]> end'