加载XDocument时是否可以使用预定义的命名空间?

我经常需要处理包含命名空间元素的XML文档,但不会声明命名空间。 例如:

   

由于前缀“a”从未分配名称空间URI,因此该文档无效。 当我使用以下代码加载这样的XML文档时:

 using (StreamReader reader = new StreamReader(new FileStream(inputFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) { doc = XDocument.Load(reader, LoadOptions.PreserveWhitespace); } 

它抛出一个exception,说明(正确地)该文档包含一个未声明的命名空间,并且格式不正确。

那么,我可以预先定义默认名称空间前缀 – >名称空间URI对,以便解析器可以依赖吗? XMLNamespaceManager看起来很有前途,但不知道如何将它应用于这种情况(或者如果我可以)。

您可以使用知道命名空间的XmlParserContext创建XmlReader ; 以下适用于XmlDocumentXDocument

 class SimpleNameTable : XmlNameTable { List cache = new List(); public override string Add(string array) { string found = cache.Find(s => s == array); if (found != null) return found; cache.Add(array); return array; } public override string Add(char[] array, int offset, int length) { return Add(new string(array, offset, length)); } public override string Get(string array) { return cache.Find(s => s == array); } public override string Get(char[] array, int offset, int length) { return Get(new string(array, offset, length)); } } static void Main() { XmlNamespaceManager mgr = new XmlNamespaceManager(new SimpleNameTable()); mgr.AddNamespace("a", "http://foo/bar"); XmlParserContext ctx = new XmlParserContext(null, mgr, null, XmlSpace.Default); using (XmlReader reader = XmlReader.Create( new StringReader(@""), null, ctx)) { XDocument doc = XDocument.Load(reader); //XmlDocument doc = new XmlDocument(); //doc.Load(reader); } } 

在前面的答案的基础上,您可以通过首先加载到XmlDocument并将XmlDocument的OuterXml解析为XDocument来保留名称空间前缀。

 XDocument LoadWithPrefix(Stream stream) { XmlNamespaceManager mgr = new XmlNamespaceManager(new NameTable()); mgr.AddNamespace("a", "http://foo/bar"); XmlParserContext ctx = new XmlParserContext(null, mgr, null, XmlSpace.Default); using (XmlReader reader = XmlReader.Create(stream, null, ctx)) { XmlDocument doc = new XmlDocument(); doc.Load(reader); return XDocument.Parse(doc.OuterXml); } }