如何设置现有XDocument的默认名称空间(以便可以使用DataContractSerializer对其进行反序列化)。我尝试了以下方法:
var doc = XDocument.Parse("<widget/>"); var attrib = new XAttribute("xmlns", "http://schemas.datacontract.org/2004/07/Widgets"); doc.Root.Add(attrib);
我得到的例外是 The prefix '' cannot be redefined from '' to 'http://schemas.datacontract.org/2004/07/Widgets' within the same start element tag.
The prefix '' cannot be redefined from '' to 'http://schemas.datacontract.org/2004/07/Widgets' within the same start element tag.
有任何想法吗?
Linq to XML似乎没有为此用例提供API(免责声明:我没有做过深入研究)。如果更改根元素的名称空间,如下所示:
XNamespace xmlns = "http://schemas.datacontract.org/2004/07/Widgets"; doc.Root.Name = xmlns + doc.Root.Name.LocalName;
仅根元素将更改其名称空间。所有子代将有一个明确的空xmlns标记。
解决方案可能是这样的:
public static void SetDefaultXmlNamespace(this XElement xelem, XNamespace xmlns) { if(xelem.Name.NamespaceName == string.Empty) xelem.Name = xmlns + xelem.Name.LocalName; foreach(var e in xelem.Elements()) e.SetDefaultXmlNamespace(xmlns); } // ... doc.Root.SetDefaultXmlNamespace("http://schemas.datacontract.org/2004/07/Widgets");
或者,如果您希望使用不会改变现有文档版本的版本:
public XElement WithDefaultXmlNamespace(this XElement xelem, XNamespace xmlns) { XName name; if(xelem.Name.NamespaceName == string.Empty) name = xmlns + xelem.Name.LocalName; else name = xelem.Name; return new XElement(name, from e in xelem.Elements() select e.WithDefaultXmlNamespace(xmlns)); }