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

Posted

技术标签:

【中文标题】为 XDocument 指定默认命名空间会给出空值【英文标题】:Specifiying a default namespace for XDocument gives empty value 【发布时间】:2015-05-27 17:15:54 【问题描述】:

当我尝试从文本中解析 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”。是不是我做错了什么?

编辑:建议重复中的答案并不能解决我的问题,即使我使用此处建议的功能: How to set the default XML namespace for an XDocument 我仍然会得到空的命名空间。以下是链接问题的解决方案:

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);
    

默认命名空间仍为空。

【问题讨论】:

How to set the default XML namespace for an XDocument的可能重复 【参考方案1】:

我想我明白为什么我没有获得默认命名空间。根据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;
    

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

【讨论】:

是的,这是最简单的方法。我一直在寻找更聪明的东西,但没有成功。【参考方案2】:

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

对于教育,添加以下内容:

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" 即可。

【讨论】:

以上是关于为 XDocument 指定默认命名空间会给出空值的主要内容,如果未能解决你的问题,请参考以下文章

包含命名空间的 XDocument

将 XElement 合并到 XDocument 并解析命名空间

使用 XDocument 生成具有多个命名空间的 XML

将 xml 命名空间添加到 XDocument

如何将 XPath 与没有前缀的默认命名空间一起使用?

mysql数据库里面的NULL属性是啥意思?