我正在使用linq-to-xml来搜索元素。
var doc = XDocument.Load(reader);
var ns = doc.Root.Attribute("xmlns").Value;
var result = (from u in doc.Descendants(XName.Get("MyElement", ns))
每当我尝试在xml中找到一个元素时,我都需要摆脱使用XName.Get。如何为XDocument设置默认命名空间,以便在搜索时不会打扰。
问候。
答案 0 :(得分:5)
如果你真的想这样做,这是忽略默认命名空间的一种方法:
XDocument doc;
using (XmlTextReader xr = new XmlTextReader("input.xml"))
{
xr.Namespaces = false;
doc = XDocument.Load(xr);
}
foreach (XElement bar in doc.Descendants("bar"))
但我建议接受XML中命名空间的存在和重要性,并使用LINQ to XML提供的XName和XNamespace对象来处理它们。
答案 1 :(得分:4)
每当我尝试在xml中找到一个元素时,我都需要摆脱使用XName.Get。如何为XDocument设置默认命名空间,以便在搜索时不会打扰。
你不能 - 但还有两个选择:
使用+(XNamespace, string)
运算符:
doc.Descendants(ns + "MyElement")
只需创建一次XName
值,然后在查询中引用它们,例如
XName myElementName = ns + "MyElement";
...
doc.Descendants(myElementName);
理想情况下,您无论如何都不会动态创建命名空间 - 您是否知道您应该查找的命名空间?如果这样做,您可以使用适当的XName
值创建私有静态只读字段。
答案 2 :(得分:1)
你不能这样做:
doc = XDocument.Load(reader);
var ns = doc.Root.Attribute("xmlns").Value;
var result = from u in doc.Descendants.Elements(ns+"MyElement").Select(c=>c.Value);
答案 3 :(得分:1)
你也可以使用LocalName,它可以使LINQ更好,但可以完成工作。 (在这种情况下从MSBuild项目文件中获取属性)。
var imports = from i in doc.Root.Elements()
where i.Name.LocalName == "Import"
from p in i.Attributes()
where p.Name.LocalName == "Project"
select p.Value;
我喜欢这样做的方式是它将XML保留为原始形式,但它向其他人暗示了一些有趣的事情正在发生。将“LocalName”放在LINQ表达式中是一种自我记录的黑客攻击。
如果代码分离,很容易忽略XmlTextReader中的命名空间。
答案 4 :(得分:0)
创建扩展方法:
public static XElement ElementInCurrentNamespace(this XElement element, string elementName)
{
return element
.Element(element.Name.Namespace.GetName(elementName));
}
public static IEnumerable<XElement> ElementsInCurrentNamespace(this XElement element, string elementName)
{
return element
.Elements(element.Name.Namespace.GetName(elementName));
}
.Element
或.Elements
方法,例如element.Element(namespace.GetName("foo"))
。答案 5 :(得分:0)
这是一篇旧帖子,但这是我的想法:
Elements.xml 根元素包含一个命名空间属性。以下代码忽略命名空间。
XDocument doc = XDocument.Load("Elements.xml");
if (doc.Root != null)
foreach (XElement xElement in doc.Root.Elements())
{
Console.WriteLine(xElement);
}