我无法在xdocument中读取子元素

时间:2014-10-17 18:02:18

标签: xml vb.net linq

这是我的XML:

<HelpDesk xmlns="http://schemas.datacontract.org/2004/07/blahblahblah" 
          xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Email>helpdesk@company.com</Email>
    <Phone>1-800-867-5309</Phone>
    <URL>https://www.company.com/</URL>
</HelpDesk>

我从Web服务收到文本字符串(如上所示)。然后,我使用以下内容创建一个XDocument对象:

Dim doc As XDocument = XDocument.Parse(responseString)

我试图抓住电子邮件,电话和网址信息。我已经尝试了很多东西,但我根本无法掌握子节点。

我尝试过的最后一件事情仍在追随,但仍然没有:

Dim email As String = doc.Root.Element("Email").Value
Dim email As String = doc.Element("Email").Value

我做错了什么?这肯定不会那么复杂。

编辑:我忘了提到我得到以下异常:

  

对象引用未设置为两次尝试的对象实例。

而且,当我尝试安德鲁的建议时,我得到同样的例外

Dim email As String = doc.Element("HelpDesk").Element("Email").Value

3 个答案:

答案 0 :(得分:2)

您不尊重文档中的 XML命名空间

<HelpDesk xmlns="http://schemas.datacontract.org/2004/07/blahblahblah" 
          ************************************************************

这是一个XML命名空间 - 您需要注意它,尊重它,将它包含在您的查询中。

使用此代码 - 并注意XML命名空间 - 然后你应该没问题:

Dim doc As XDocument = XDocument.Parse(responseString)

' define the XNamespace that you need!    
Dim ns As XNamespace = "http://schemas.datacontract.org/2004/07/blahblahblah"

' include the XNamespace in your XPath query    
Dim emailNode = doc.Root.Descendants(ns & "Email").FirstOrDefault()

If emailNode IsNot Nothing Then
    Dim email As String = emailNode.Value
End If

您应该同时始终保持对您的节目的防御 - 不要盲目地认为通话有效 - 检查它!。因此 - 不要盲目地认为emailNode有效 - 可以为空!检查一下 - 只有访问.Value != null属性{{1}} ....

答案 1 :(得分:0)

使用LINQ

选择正确的节点
Dim contact As XElement =
    <HelpDesk xmlns="http://schemas.datacontract.org/2004/07/blahblahblah" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <Email>helpdesk@company.com</Email>
        <Phone>1-800-867-5309</Phone>
        <URL>https://www.company.com/</URL>
    </HelpDesk>
Dim responseString = contact.ToString()
Dim doc As XDocument = XDocument.Parse(responseString)

Dim email = doc.Root.Elements.Where(Function(xe) xe.Name.LocalName = "Email").FirstOrDefault().Value
Dim phone = doc.Root.Elements.Where(Function(xe) xe.Name.LocalName = "Phone").FirstOrDefault().Value
Dim url = doc.Root.Elements.Where(Function(xe) xe.Name.LocalName = "URL").FirstOrDefault().Value

答案 2 :(得分:0)

您的查询不会返回结果,因为您忽略了节点所属的命名空间,而是请求空命名空间。

你得到&#34;对象引用未设置为&#34;因为你使用的是C#访问XML的方式而不是空字符串。

要解决这两个问题,请将XML名称空间声明添加到代码模块的开头:

Imports <xmlns="http://schemas.datacontract.org/2004/07/blahblahblah">
Imports <xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

并像在VB中一样查询XML:

Dim email As String = doc.<HelpDesk>.<Email>.Value

作为默认Import命名空间的命名空间xmlns将自动应用于此模块中的所有非限定查询。如果您发现这一点令人困惑,您可以使用其他一些前缀声明该命名空间,例如:

Imports <xmlns:x="http://schemas.datacontract.org/2004/07/blahblahblah">

然后就是

Dim email As String = doc.<x:HelpDesk>.<x:Email>.Value

以这种方式查询XML时,您不必担心查询路径中的某些节点为null或不存在。如果是,则整个查询将返回一个空字符串,而不会引发异常。