为XDocument指定默认名称空间会给出空值

本文关键字:空间 空值 XDocument 默认 | 更新日期: 2023-09-27 17:50:52

当我尝试从文本解析XDocument时,我可以得到这样的默认名称空间:

var xmlDocument1 = XDocument.Parse("<root xmlns='http://somenamespace'></root>");
var xmlNamespace1 = xmlDocument1.Root.GetDefaultNamespace().NamespaceName; // somenamespace

但是,如果我尝试手动创建XDocument,我会得到一个空值:

var xmlRoot2 = new XElement(XName.Get("root", "http://somenamespace"));
var xmlDocument2 = new XDocument(xmlRoot2);
var xmlNamespace2 = xmlDocument2.Root.GetDefaultNamespace().NamespaceName; // is empty

我期望xmlNamespace2为"http://somenamespace"。我做错了什么吗?

编辑:建议重复的答案并不能解决我的问题,即使我使用这里建议的函数:如何为XDocument设置默认的XML名称空间我仍然会得到空的命名空间。下面是链接问题的答案:

class Program
{
    static void Main(string[] args)
    {
        var xmlRoot = new XElement(XName.Get("root"));
        var xmlDocument = new XDocument(xmlRoot);
        SetDefaultXmlNamespace(xmlRoot, "http://somenamespace");
        var xmlNamespace = xmlDocument.Root.GetDefaultNamespace().NamespaceName; // is empty
    }
    public static void SetDefaultXmlNamespace(XElement xelem, XNamespace xmlns)
    {
        if (xelem.Name.NamespaceName == string.Empty)
            xelem.Name = xmlns + xelem.Name.LocalName;
        foreach (var e in xelem.Elements())
            SetDefaultXmlNamespace(e, xmlns);
    }
}

默认命名空间仍然为空

为XDocument指定默认名称空间会给出空值

我想我明白为什么我没有得到默认名称空间。根据MSDN:

当使用c#创建XML树时,即使XML树是如果名称空间没有持久化,则使用默认名称空间序列化在XML树中作为属性,此方法将不会报告

所以我可能需要显式设置xmlns属性:
class Program
{
    static void Main(string[] args)
    {
        var xmlRoot = new XElement(XName.Get("root", "http://somenamespace"));
        xmlRoot.SetAttributeValue("xmlns", "http://somenamespace");
        var xmlDocument = new XDocument(xmlRoot);
        var xmlNamespace = xmlDocument.Root.GetDefaultNamespace().NamespaceName;
    }
}

现在我得到了正确的名称空间名称。

是的,这很棘手,因为即使字符串表示看起来很好,它仍然不起作用。

对于教育,添加如下:

var xml3 = xmlDocument2.ToString();
var xmlDocument3 = XDocument.Parse(xml3);            
var xmlNamespace3 = xmlDocument3.Root.GetDefaultNamespace().NamespaceName;

所以只有在你再次解析xml文本之后,它才会是你所期望的。

最短的方法可能是:

var xmlRoot2 = new XElement(XName.Get("root", "http://somenamespace"), 
       new XAttribute("xmlns", "http://somenamespace"));

使用预定义的XNameSpace.Xmlns不能用于默认的(没有前缀的)命名空间,所以只能使用"xmlns"