XmlDocument忽略xmlns

6

我有一个以以下内容开头的XHTML文件:

<html xmlns="http://www.w3.org/1999/xhtml">

我加载它:
XmlDocument xml = new XmlDocument();
StringReader sr = new StringReader(html);
XmlTextReader xmltr = new XmlTextReader(sr);
xmltr.Namespaces = false;
xml.Load(xmltr);

当我调用 xml.InnerXml 时,总是会得到 The 'xmlns' attribute is bound to the reserved namespace 'http://www.w3.org/2000/xmlns/'. 的异常,无法访问我的 XmlDocument 的内部 xml。如何在加载过程中摆脱 xmlns?

解决方案是:

XmlNode xmln = xml.SelectSingleNode("//html");
if (xmln != null)
    ((XmlElement)xmln).RemoveAttribute("xmlns");

是的,它不起作用。当您尝试以任何方式触摸此节点时,您将始终收到异常。但是对于所有其他节点,一切都正常。您仍然可以通过XPath获取任何内部节点(正如我所做的那样)。如何修复? - Denis
好的,我刚刚重现了这个问题 - 如果你去掉“Namespaces = false”这一行,它就会消失。你为什么要这样做? - Jon Skeet
我不记得了。但是如果没有它,xml.SelectSingleNode("//title")无法工作,我目前正在研究它。如果您知道解决方案,我将非常感谢您的帮助。 - Denis
嗯,是的,您需要更改XPath以考虑命名空间...或使用其他东西。个人而言,我更喜欢在XML工作中使用LINQ to XML...您能否改用它? - Jon Skeet
我已经有相当大量的工作代码了,XmlDocument符合我的需求。我使用SelectSingleNode来处理一些深层节点。目前我正在寻找为什么XPath停止工作的原因。但是还没有找到答案。 - Denis
显示剩余5条评论
1个回答

6
猜测您要解析的页面最近更改为XHTML,因此需要命名空间?根据@JonSkeet的建议,不应在XmlTextReader上设置xmltr.Namespaces = false;。您可以选择接受命名空间并使用XmlNameSpaceManager来管理XHTML(xmlns="http://www.w3.org/1999/xhtml")命名空间,或者使用忽略命名空间的xpath,如local-name(),它将忽略命名空间:*
 xml.SelectSingleNode("/*[local-name()='html']/*[local-name()='body']")

无论哪种方式,您的代码都需要更改以适应命名空间,除非您在加载XML之前将命名空间从XML中删除。

* 您还可以使用//和 local-name(),但对于具有大量元素的文档要小心-这可能会变得非常慢。


2
谢谢,nonnb。我已经使用((XmlElement)xmln).RemoveAttribute("xmlns");删除了命名空间属性。 - Denis

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