命名空间属性在 .outerHTML 中不存在

namespace attributes not present in .outerHTML

提问人:mathheadinclouds 提问时间:5/31/2020 最后编辑:mathheadinclouds 更新时间:7/11/2020 访问量:383

问:

在 HTML5/JavaScript 中,如果我以编程方式创建一个命名空间的 dom 节点,如下所示:

svgElt = document.createElementNS("http://www.w3.org/2000/svg", 'svg')

节点“知道”它自己的命名空间,我可以像这样检索:

svgElt.namespaceURI // result: "http://www.w3.org/2000/svg"

但命名空间不被视为“正常”属性:

svgElt.getAttribute('xmlns') // result: null

因此,以编程方式创建的节点的行为与等效的“直接”节点不同

<svg xmlns="http://www.w3.org/2000/svg" id="mySVG"></svg>

适用于:.getAttribute

document.getElementById('mySVG').getAttribute('xmlns') // result: "http://www.w3.org/2000/svg"

当我使用和需要结果中包含的命名空间信息时,这是一个潜在的问题。对于以编程方式创建的节点,命名空间信息可能会丢失,我可能需要手动添加它;这似乎是一件“我不应该关心”的事情——因此是问题所在。.outerHTML

您需要在其中包含命名空间信息的一个例子是(请参阅这个问题,Hubert OG 的答案)当您想通过将图像源设置为数据 url 来将内联 SVG 节点转换为 ,如.outerHTMLImage

'data:image/svg+xml,' + your_svg_element.outerHTML

我所做的是

svgNode.setAttribute('xmlns', svgNode.namespaceURI)

SVG -> 没有这个技巧,图像转换(正如我实现的那样)是行不通的;另请参阅我对上面链接的问题的回答。

有没有更好/更优雅的方法来做到这一点?返回的目的是什么?缺陷还是功能?svgElt.getAttribute('xmlns')null

JavaScript SVG DOM 命名空间 XHTML

评论

0赞 Robert Longson 5/31/2020
我说的是文档的 mime 类型
0赞 mathheadinclouds 6/1/2020
@RobertLongson:当然。所以你是说,如果我改变我提供文档的 mime 类型,在某个 dom 节点上调用 .outerHTML 的结果会发生变化,我理解正确吗?
1赞 Alohci 6/1/2020
@mathheadinclouds - 是的,它可以。它们所提供的 mime 类型会导致正在构造的 HTML 文档或 XML 文档。您还可以在 JavaScript 中创建任一类型的文档。读取 .outerHTML 因文档类型而异。DOM 解析和序列化规范中描述了这两种类型的算法之间的差异
1赞 Alohci 6/1/2020
FWIW,你描述的属性和命名空间的分离 Uri 问题可以追溯到 DOM 最初所做的妥协,从那时起就一直是沮丧和困惑的根源。其他对象模型 API 修复了这个问题和一些类似的问题,已经在其他地方尝试和使用过,但对于浏览器中的 JS,DOM 经受住了考验。向后兼容性限制意味着必须保留古怪的行为。

答:

0赞 mathheadinclouds 6/2/2020 #1

请先阅读问题下的评论。

以下是我们如何通过“xhtml-ifying”dom 节点,然后调用 来获取带有命名空间信息的 html,然后将是 xhtml(并具有 html 缺少的命名空间信息)。.outerHTML

function outerXHTML(node){
    var nsx = "http://www.w3.org/1999/xhtml";
    var xdoc = document.implementation.createDocument(nsx, 'html');
    xdoc.documentElement.appendChild(node);
    return node.outerHTML;
}
function innerXHTML(node){
    var nsx = "http://www.w3.org/1999/xhtml";
    var xdoc = document.implementation.createDocument(nsx, 'html');
    xdoc.documentElement.appendChild(node);
    return node.innerHTML;
}

(如果节点应保留在原始文档中,请先克隆节点。

相关问题(X/HTML 转换)

相关问题(文档创建)

用于测试 HTML 到 XHTML 转换的小提琴

使用文本框中的任意 HTML 字符串测试 Kaiido 版本

1赞 Kaiido 7/11/2020 #2

为此,您可以简单地使用 XMLSerializer,它会将您的 DOM 树字符串化为 xml,从而保留命名空间。

const svgElt = document.createElementNS("http://www.w3.org/2000/svg", 'svg')
const serialized = new XMLSerializer().serializeToString(svgElt);
console.log(serialized);