去除自动添加的xmlns属性

4
我将尝试在Javascript中执行一个简单的搜索和高亮功能,以搜索一段文字。该文本所在的XHTML标记也作为参数给出,以帮助定位该文本。
我正在测试此功能的XHTML如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta content="application/xml+xhtml;charset=UTF-8" />
<script src="searcher.js" type="text/javascript"></script>
<script src="jquery-2.0.2.min.js"> </script>
<title>Building your resume</title>
</head>
<body id="highlightbegin">
<h1>Building your resume</h1>

<div> <input name="input" type="button" value="Highlight3" onclick="javascript:searcher('&lt;h1&gt;','Building your resume', '&lt;h1&gt;Building your resume', 'resume');" /> </div>

</body>
</html>  

在 searcher.js 中的函数 searcher:
function searcher(tag, text, tagText, word) {

    //simple search.
    console.info(word + " to be searched for in " + text + " with tag text = " + tagText);

    //get old html.
    var oldHTML = document.getElementById("highlightbegin").innerHTML;

    //get regexp.
    var regexp = new RegExp(tagText, 'g');

    var match = oldHTML.match(regexp);
    console.info(text + " found " + match.length + " times.");
}  

然而,执行RegExp时,匹配返回null。进一步调查发现,标签<h1>Building your resume</h1>变成了<h1 xmlns="http://www.w3.org/1999/xhtml">Building your resume</h1>,这导致match函数返回null。我的问题是:
  1. 为什么会自动添加xmlns属性?
  2. 有没有办法防止该属性被添加?
  3. 该属性会添加到哪些标签中?可以假设它会添加到每个标签吗?
  4. 这是一个特定于浏览器的问题,还是所有浏览器都会出现这种行为?
编辑:
一个观察结果:
1. 如果我将xmlns属性添加到标签中,并使用outerHTML访问所有内容(var oldHTML = document.getElementById("highlightbegin").outerHTML;),则其子元素不具有xmlns属性。
我的问题是:
1. 可以用Javascript编辑并替换outerHTML元素吗?
2. 上述观察结果是一致的(每次调用outerHTML时都会看到)还是实现有关?
3. 是Javascript自动添加xmlns属性还是浏览器?

如果您将doctype更改为 <!DOCTYPE html>,那么我相信这将改善行为。 - Daniel Gimenez
1个回答

3
Why is the xmlns attribute added automatically?

因为如果不这样做,标记语言就无法代表DOM中元素的命名空间。如果您将该字符串重新写回DOM,则浏览器将不再将元素解释为HTML元素,导致您的页面崩溃。

Is there a way to prevent the attribute from being added?

如果你正在使用 XMLDocument,那么不能使用 innerHTML。如果需要,可以通过遍历 DOM 树来创建自己的序列化器。

What tags will that attribute be added to? Is it safe to assume that it will be 
added to every tag?

至少需要翻译该元素的顶层子标签,假设该子标签不在空名称空间中。还有任何与其父元素不同名称空间的后代元素的开始标签。如果浏览器选择这样做,将所有开始标签都添加到其中也不会有错。

Is this a browser-specific issue or can this behavior be expected in all browsers?

使用innerHTML序列化DOM在不同的浏览器上传统上会有所不同。尽管浏览器应该保持一致,但我不会依赖于它。

1. Can the outerHTML element be edited (with Javascript) and replaced?

理论上是可以的,但这并没有什么帮助。你需要用一个处于“null”命名空间的元素来替换该元素,以防止该属性出现在外部元素上,但这只会导致outerHTML将该属性添加到子元素中(因为它们与其父元素具有不同的命名空间)。

2. Is the observation above consistent (seen each time outerHTML is invoked) or is 
   it implementation dependent?

出于与innerHTML相同的原因,有些地方需要序列化添加属性,以便字符串可以成功读回,并且某些情况下浏览器可能会选择添加属性。但是这并不能保证一直保持一致。

3. Is it Javascript that adds the xmlns attribute automatically or the browser?

这是浏览器内置的将DOM序列化为字符串的过程。通常情况下,该属性不在DOM元素上( <html>元素是正常例外),它会在转换为字符串时由浏览器自动添加到任何被认为必要的位置。
总的来说,这也是专家们试图劝阻尝试使用正则表达式处理HTML标记的原因之一。即使与XHTML相比,其中没有这个命名空间的问题需要担心,在字符串和DOM表单之间进行转换时,属性可以被添加和删除,并且它们的顺序可能以任意方式改变,没有关于不同浏览器制造商之间的一致性保证,甚至是同一浏览器制造商的连续版本。

你最后的评论特别正确。你不能依赖于innerHTML是一个完全匹配的结果。https://dev59.com/sW865IYBdhLWcg3wQMSW - Daniel Gimenez
@Alohci:感谢您的回复。我在原有问题底部添加了几个更多的问题。请帮忙查看一下吗? - Sriram

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接