忽略LINQ to XML中的名称空间

如何让LINQ to XML iqnore所有的命名空间? 或者,如何去掉命名空间?

我在问,因为命名空间是以半随机方式设置的,而且我厌倦了search带有和不带有命名空间的节点。

而不是写作:

nodes.Elements("Foo") 

写:

 nodes.Elements().Where(e => e.Name.LocalName == "Foo") 

当你感到厌倦的时候,制定你自己的扩展方法:

 public static IEnumerable<XElement> ElementsAnyNS<T>(this IEnumerable<T> source, string localName) where T : XContainer { return source.Elements().Where(e => e.Name.LocalName == localName); } 

如果你必须经常处理命名空间的属性(这是比较less见的),那么同样是属性。

[编辑]添加XPath的解决scheme

对于XPath,而不是写入:

 /foo/bar | /foo/ns:bar | /ns:foo/bar | /ns:foo/ns:bar 

你可以使用local-name()函数:

 /*[local-name() = 'foo']/*[local-name() = 'bar'] 

这是一个剥离命名空间的方法:

 private static XElement StripNamespaces(XElement rootElement) { foreach (var element in rootElement.DescendantsAndSelf()) { // update element name if a namespace is available if (element.Name.Namespace != XNamespace.None) { element.Name = XNamespace.None.GetName(element.Name.LocalName); } // check if the element contains attributes with defined namespaces (ignore xml and empty namespaces) bool hasDefinedNamespaces = element.Attributes().Any(attribute => attribute.IsNamespaceDeclaration || (attribute.Name.Namespace != XNamespace.None && attribute.Name.Namespace != XNamespace.Xml)); if (hasDefinedNamespaces) { // ignore attributes with a namespace declaration // strip namespace from attributes with defined namespaces, ignore xml / empty namespaces // xml namespace is ignored to retain the space preserve attribute var attributes = element.Attributes() .Where(attribute => !attribute.IsNamespaceDeclaration) .Select(attribute => (attribute.Name.Namespace != XNamespace.None && attribute.Name.Namespace != XNamespace.Xml) ? new XAttribute(XNamespace.None.GetName(attribute.Name.LocalName), attribute.Value) : attribute ); // replace with attributes result element.ReplaceAttributes(attributes); } } return rootElement; } 

用法示例:

 XNamespace ns = "http://schemas.domain.com/orders"; XElement xml = new XElement(ns + "order", new XElement(ns + "customer", "Foo", new XAttribute("hello", "world")), new XElement("purchases", new XElement(ns + "purchase", "Unicycle", new XAttribute("price", "100.00")), new XElement("purchase", "Bicycle"), new XElement(ns + "purchase", "Tricycle", new XAttribute("price", "300.00"), new XAttribute(XNamespace.Xml.GetName("space"), "preserve") ) ) ); Console.WriteLine(xml.Element("customer") == null); Console.WriteLine(xml); StripNamespaces(xml); Console.WriteLine(xml); Console.WriteLine(xml.Element("customer").Attribute("hello").Value); 

当我发现这个问题寻找一个简单的方法来忽略名称空间的属性,这里是一个扩展名时忽略名称空间访问属性,基于帕维尔的答案(为了更容易复制,我包括他的扩展名):

 public static XAttribute AttributeAnyNS<T>(this T source, string localName) where T : XElement { return source.Attributes().SingleOrDefault(e => e.Name.LocalName == localName); } public static IEnumerable<XElement> ElementsAnyNS<T>(this IEnumerable<T> source, string localName) where T : XContainer { return source.Elements().Where(e => e.Name.LocalName == localName); }