You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

遍历XDocument获取XML元素值时出现对象引用错误求助

VB.NET遍历XDocument时对象引用错误的排查与解决

问题描述

在VB.NET中编写代码遍历XDocument提取XML元素值时,foreach循环内的元素值获取操作触发了对象引用未设置为实例的错误,相关代码如下:

Dim lstrReadXml As String = String.Empty
mobjComFun.ReadTextFile(System.Windows.Forms.Application.StartupPath & "\GoFirstBookingXML\GetBookRes.xml", lstrReadXml)
Dim lobjXdoc As XDocument = XDocument.Parse(lstrReadXml)
Dim lobjNs As New XmlNamespaceManager(lobjXdoc.CreateReader.NameTable)
lobjNs.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/")
lobjNs.AddNamespace("sc", "http://schemas.navitaire.com/WebServices/ServiceContracts/BookingService")
lobjNs.AddNamespace("dc", "http://schemas.navitaire.com/WebServices/DataContracts/Booking")
lobjNs.AddNamespace("a", "http://schemas.navitaire.com/WebServices/DataContracts/Common")
 
Dim lstrErrorMsg = String.Empty, lstrQueryStr As String = String.Empty
Dim lstrPaxNames As New StringBuilder
'Dim lstrFirstName As String = mobjComFun.GetElementValue(lobjXdoc, "/s:Envelope/s:Body/sc:GetBookingResponse/dc:Booking/dc:Passengers/dc:Passenger/dc:Names", lobjNs, lstrErrorMsg)
For Each lobXnode In lobjXdoc.XPathSelectElements("/s:Envelope/s:Body/sc:GetBookingResponse/dc:Booking/dc:Passengers/dc:Passenger", lobjNs)
    If Not lobXnode Is Nothing Then
        Dim lobjIEnum As IEnumerable(Of XElement) = From Nam In lobXnode.Elements(lobjNs. & "Names")
                                                    Select Nam

        Dim lstrLN As String = lobXnode.Document.Element("LastName").Value
        lstrPaxNames.Append(lobXnode.XPathSelectElement("/dc:Names", lobjNs).Value)
        lstrPaxNames.Append(lobXnode.XPathSelectElement("/dc:Names/dc:BookingName/dc:LastName", lobjNs).Value & "/")
        lstrPaxNames.Append(lobXnode.XPathSelectElement("/dc:Names/dc:BookingName/dc:FirstName", lobjNs).Value & " Y58TWL ")

    End If
Next

错误原因分析

  1. 语法错误:lobjNs. & "Names"存在语法错误,无法正确引用命名空间
  2. 路径错误:
    • lobXnode.Document.Element("LastName")从整个文档根节点查找元素,而非当前Passenger节点,且未指定命名空间,必然返回Nothing
    • XPath表达式"/dc:Names"是绝对路径,从文档根开始查找,而非当前Passenger节点的子元素
  3. 未做空值判断:直接访问XPathSelectElement返回结果的Value属性,若元素不存在则触发对象引用错误

修正后的代码

Dim lstrReadXml As String = String.Empty
mobjComFun.ReadTextFile(System.Windows.Forms.Application.StartupPath & "\GoFirstBookingXML\GetBookRes.xml", lstrReadXml)
Dim lobjXdoc As XDocument = XDocument.Parse(lstrReadXml)
Dim lobjNs As New XmlNamespaceManager(lobjXdoc.CreateReader.NameTable)
lobjNs.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/")
lobjNs.AddNamespace("sc", "http://schemas.navitaire.com/WebServices/ServiceContracts/BookingService")
lobjNs.AddNamespace("dc", "http://schemas.navitaire.com/WebServices/DataContracts/Booking")
lobjNs.AddNamespace("a", "http://schemas.navitaire.com/WebServices/DataContracts/Common")

' 定义命名空间对象,简化元素查找
Dim dcNs As XNamespace = "http://schemas.navitaire.com/WebServices/DataContracts/Booking"

Dim lstrErrorMsg = String.Empty, lstrQueryStr As String = String.Empty
Dim lstrPaxNames As New StringBuilder

For Each lobXnode In lobjXdoc.XPathSelectElements("/s:Envelope/s:Body/sc:GetBookingResponse/dc:Booking/dc:Passengers/dc:Passenger", lobjNs)
    If lobXnode IsNot Nothing Then
        ' 从当前Passenger节点逐级查找子元素,每一步做空值判断
        Dim namesElement = lobXnode.Element(dcNs + "Names")
        If namesElement IsNot Nothing Then
            Dim bookingNameElement = namesElement.Element(dcNs + "BookingName")
            If bookingNameElement IsNot Nothing Then
                Dim lastNameElement = bookingNameElement.Element(dcNs + "LastName")
                Dim firstNameElement = bookingNameElement.Element(dcNs + "FirstName")
                
                ' 确保元素存在再取值
                If lastNameElement IsNot Nothing Then
                    lstrPaxNames.Append(lastNameElement.Value & "/")
                End If
                If firstNameElement IsNot Nothing Then
                    lstrPaxNames.Append(firstNameElement.Value & " Y58TWL ")
                End If
            End If
        End If

        ' 备选方案:使用相对路径XPath
        ' Dim lastName = lobXnode.XPathSelectElement("./dc:Names/dc:BookingName/dc:LastName", lobjNs)
        ' Dim firstName = lobXnode.XPathSelectElement("./dc:Names/dc:BookingName/dc:FirstName", lobjNs)
        ' If lastName IsNot Nothing Then lstrPaxNames.Append(lastName.Value & "/")
        ' If firstName IsNot Nothing Then lstrPaxNames.Append(firstName.Value & " Y58TWL ")
    End If
Next

关键修正点

  • 用XNamespace对象创建带命名空间的元素名,避免语法错误
  • 从当前Passenger节点逐级查找子元素,确保路径正确
  • 每一步都判断元素是否为Nothing,再访问Value属性
  • XPath方式改用相对路径./,从当前节点开始查找而非文档根

内容的提问来源于stack exchange,提问作者Naresh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 17:50:36