小编典典

如何为XDocument设置默认的XML名称空间

c#

如何设置现有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.

有任何想法吗?


阅读 237

收藏
2020-05-19

共1个答案

小编典典

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));
}
2020-05-19