【问题标题】:Getting an XML element获取 XML 元素
【发布时间】:2013-07-29 14:27:14
【问题描述】:

在下面的程序中,helloElem 不为空,正如预期的那样。

string xml = @"<root>
<hello></hello>
</root>";

XDocument xmlDoc = XDocument.Parse(xml);
var helloElem = xmlDoc.Root.Element("hello"); //not null

如果给 XML 一个命名空间:

string xml = @"<root xmlns=""namespace"">
<hello></hello>
</root>";

XDocument xmlDoc = XDocument.Parse(xml);
var helloElem = xmlDoc.Root.Element("hello"); //null

为什么helloElem 变为空?在这种情况下如何获取 hello 元素?

【问题讨论】:

    标签: c# .net xml linq linq-to-xml


    【解决方案1】:

    你当然可以摆脱namespaces,见下文:

    string xml = @"<root>
                       <hello></hello>
                   </root>";
    
     XDocument xmlDoc = XDocument.Parse(xml);
     var helloElem = xmlDoc.Descendants().Where(c => c.Name.LocalName.ToString() == "hello");
    

    以上代码可以处理带有或不带有namespaces 的节点。请参阅 Descendants() 了解更多信息。希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      如下操作

      XDocument xmlDoc = XDocument.Parse(xml);
      XNamespace  ns = xmlDoc.Root.GetDefaultNamespace();
      var helloElem = xmlDoc.Root.Element(ns+ "hello"); 
      

      【讨论】:

        【解决方案3】:

        试试

         XNamespace ns = "namespace";
         var helloElem = xmlDoc.Root.Element(ns + "hello"); 
        

        【讨论】:

        • 这行得通,但是是否可以让代码支持所有情况,有/没有命名空间并且不对命名空间进行硬编码?
        • @roger.james 这就像要求 C# 编译器忽略命名空间并尝试在您的项目中找到匹配的对象。就像您的项目一样,XML 中的命名空间有助于区分 candy:barfoo:bar,这肯定是两个截然不同的东西。
        【解决方案4】:

        这是一个默认的命名空间 XPath。

        private static XElement XPathSelectElementDefaultNamespace(XDocument document,
                                                                   string element)
        {
            XElement result;
            string xpath;
        
            var ns = document.Root.GetDefaultNamespace().ToString();
        
            if(string.IsNullOrWhiteSpace(ns))
            {
                xpath = string.Format("//{0}", element);
                result = document.XPathSelectElement(xpath);
            }
            else
            {
                var nsManager = new XmlNamespaceManager(new NameTable());
                nsManager.AddNamespace(ns, ns);
        
                xpath = string.Format("//{0}:{1}", ns, element);
                result = document.XPathSelectElement(xpath, nsManager);
            }
        
            return result;
        }
        

        用法:

        string xml1 = @"<root>
        <hello></hello>
        </root>";
        
        string xml2 = @"<root xmlns=""namespace"">
        <hello></hello>
        </root>";
        
        var d = XDocument.Parse(xml1);
        Console.WriteLine(XPathSelectElementDefaultNamespace(d, "hello"));
        // Prints: <hello></hello>
        
        d = XDocument.Parse(xml2);
        Console.WriteLine(XPathSelectElementDefaultNamespace(d, "hello"));
        // Prints: <hello xmlns="namespace"></hello>
        

        【讨论】:

          猜你喜欢
          • 2018-08-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-11
          • 1970-01-01
          相关资源
          最近更新 更多