使用XElement的Elements(XName)方法时出现Linq To Xml问题

3

我是一个有用的助手,可以为您翻译文本。

我有一个使用Linq To Xml的问题。

这是一个简单的代码。我有这个XML:

<?xml version="1.0" encoding="utf-8" ?>
<data xmlns="http://www.example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/directory file.xsd">
<contact>
 <name>aaa</name>
 <email>email@email.ext</email>
 <birthdate>2002-09-22</birthdate>
 <telephone>000:000000</telephone>
 <description>Description for this contact</description>
</contact>
<contact>
 <name>sss</name>
 <email>email@email.ext</email>
 <birthdate>2002-09-22</birthdate>
 <telephone>000:000000</telephone>
 <description>Description for this contact</description>
</contact>
<contact>
 <name>bbb</name>
 <email>email@email.ext</email>
 <birthdate>2002-09-22</birthdate>
 <telephone>000:000000</telephone>
 <description>Description for this contact</description>
</contact>
<contact>
 <name>ccc</name>
 <email>email@email.ext</email>
 <birthdate>2002-09-22</birthdate>
 <telephone>000:000000</telephone>
 <description>Description for this contact</description>
</contact>

我希望将每个联系人映射到一个名为Contact的对象上。为此,我使用以下代码片段:

我想要获取每个联系人并将其映射到一个名为Contact的对象上。为了实现这一目标,我使用了以下代码片段:

XDocument XDoc = XDocument.Load(System.Web.HttpRuntime.AppDomainAppPath + this.filesource);
XElement XRoot = XDoc.Root;
//XElement XEl = XElement.Load(this.filesource);
var results = from e in XRoot.Elements("contact") 
 select new Contact((string)e.Element("name"), (string)e.Element("email"), "1-1-1", null, null);
List<Contact> cntcts = new List<Contact>();
foreach (Contact cntct in results) {
 cntcts.Add(cntct);
}
Contact[] c = cntcts.ToArray();
// Encapsulating element
Elements<Contact> final = new Elements<Contact>(c);

好的,不要关注前面的内容,重点在这里:

当我获取根节点时,一切都没问题,我成功地获取了它。

当我使用选择指令尝试获取每个节点时,我会写成:从 e in

XRoot.Elements("contact")

好的,这里是问题:如果我使用:from e in XRoot.Elements(),我会得到所有联系人节点,但如果我使用:from e in XRoot.Elements("contact"),我什么也得不到:空集。

好吧,你告诉我:使用另一个:好的,那么我们使用:from e in XRoot.Elements(),我无论如何都能得到所有节点,没错,但是接下来就出现了另一个问题: 当说: select new Contact((string)e.Element("name"), (string)e.Element("email"), "1-1-1", null, null); 我试图访问<name>, <email>... 我必须使用.Element("name"),但它也不起作用!!!这是怎么回事?似乎它不匹配我传递的名称。但这怎么可能呢?我知道Elements()函数可以重载,接受一个XName参数,该参数映射到一个字符串。请注意,我所写的代码来自一个例子,它应该工作。


欢迎来到Stackoverflow - 一个建议:如果您发布代码片段或XML片段,请突出显示这些行并单击编辑器工具栏中的“代码”按钮(101 010)以正确格式化它们。这将使您的帖子更加美观和易读! - marc_s
2个回答

16

很简单:这里使用了XML命名空间,而您忽略了它:

<data xmlns="http://www.example.com"  
      **************************

你需要将这个添加到你的Linq-to-XML查询中!

类似于这样:

XNamespace ns = "http://www.example.com";

接着

XRoot.Elements(ns + "contact") 

当然,在访问子元素时也要使用XML命名空间:

var results = from e in XRoot.Elements("contact") 
              select new Contact(e.Element(ns + "name").Value, 
                                 e.Element(ns + "email").Value, 
                                 "1-1-1", null, null);

那应该有所帮助。请参阅MSDN关于使用XML命名空间的文档获取更多详细信息。


这可能是我对linq2xml API唯一的抱怨。大多数我所工作的软件都不关心命名空间,但无论如何都需要编写代码来处理它。 - Frank Schwieterman
2
@Frank:但是如果你的API明显忽略了命名空间(专门设计用于消除相同名称元素的歧义),那么拥有命名空间有什么好处呢??这对我来说真的没有太多意义... - marc_s
真的...我现在试一下,不管怎样,非常感谢,太不可思议了,你回答得这么快...真的谢谢,我会告诉你进展如何的...只是需要尝试一下 :) - Dorian McHensie
好的,它起作用了...非常感谢。我之前并没有真正关注命名空间 :) 非常感谢! - Dorian McHensie
1
命名空间在 XML 中非常有用,但我很少需要从不同的命名空间中读取。不断重新指定命名空间的需求似乎有些过度。 - Frank Schwieterman
3
如果您愿意,可以忽略命名空间:XRoot.Elements().Where(e => e.Name.LocalName == "contact")。 - Stephen Oberauer

0

对我来说,我是这样解决的,因为我的 XML 中没有命名空间:

xmldoc.Root.Elements("contact");

我忘记使用“Root”方法了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接