【问题标题】:c# Retrieve multiple XML child nodesc# 检索多个 XML 子节点
【发布时间】:2014-12-06 01:03:26
【问题描述】:

我已经成功地将单个 XElement 链接到我的程序中,尽管我已经尝试使用其他两个,但我没有任何运气;

IEnumerable 查询 = 来自 doc.Descendants("Booking") 中的预订

虽然我没有太多运气将值放入列表框中。

函数代码如下:

    private void btnimport_Click(object sender, EventArgs e)
    {
        OpenFileDialog open = new OpenFileDialog();
        open.CheckFileExists = true;
        open.InitialDirectory = "@C:\\";
        open.Filter = "XML Files (*.xml)|*.xml|All Files(*.*)|*.*";
        open.Multiselect = false;

        if (open.ShowDialog() == DialogResult.OK)
        {
            try
            {
                XDocument doc = XDocument.Load(open.FileName);

                //Grabs the customer elements
                var query = from booking in doc.Descendants("Booking")
                select new
                {
                    //Customer Elements
                    CustomerId = booking.Element("CustomerId").Value,
                    Title = booking.Element("Title").Value,
                    Firstname = booking.Element("FirstName").Value,
                    Lastname = booking.Element("LastName").Value,
                    DateofBirth = booking.Element("DateofBirth").Value,
                    Email = booking.Element("Email").Value,
                    HouseNo = booking.Element("HouseNo").Value,
                    Street = booking.Element("Street").Value,
                    Postcode = booking.Element("Postcode").Value,
                    Town = booking.Element("Town").Value,
                    County = booking.Element("County").Value,
                    ContactNo = booking.Element("ContactNo").Value,

                    //Holiday Elements
                    HolidayId = booking.Element("HolidayId").Value,
                    HotelName = booking.Element("HotelName").Value,
                    Location = booking.Element("Location").Value,
                    BookFrom = booking.Element("BookFrom").Value,
                    BookTo = booking.Element("BookTo").Value,
                    CheckInTime = booking.Element("CheckInTime").Value,
                    CheckOutTime = booking.Element("CheckOutTime").Value,
                    NoOfRoomsBooked = booking.Element("NoOfRoomsBooked").Value,
                    RoomType = booking.Element("RoomType").Value,
                    RoomServices = booking.Element("RoomServices").Value,
                    Parking = booking.Element("Parking").Value,
                    Pet = booking.Element("Pet").Value,

                    //TravelInfo Elements
                    TravelInfoId = booking.Element("TravelInfoId").Value,
                    TravellingFrom = booking.Element("TravellingFrom").Value,
                    Destination = booking.Element("Destination").Value,
                    Fare = booking.Element("Fare").Value,
                    TravelInsurance = booking.Element("TravelInsurance").Value,
                    InFlightMeals = booking.Element("In-FlightMeals").Value,
                    LuggageAllowance = booking.Element("LuggageAllowance").Value,
                    ExtraLuggage = booking.Element("ExtraLuggage").Value,
                    CarHire = booking.Element("CarHire").Value,
                    ReturnTransfer = booking.Element("ReturnTransfer").Value,
                };

                //Inputs all of the values in bookings
                foreach (var booking in query)
                {
                    //Customer values
                    txtCustomerId.Text = txtCustomerId.Text + booking.CustomerId;
                    txttitle.Text = txttitle.Text + booking.Title;
                    txtfname.Text = txtfname.Text + booking.Firstname;
                    txtlname.Text = txtlname.Text + booking.Lastname;
                    txtdob.Text = txtdob.Text + booking.DateofBirth;
                    txtemail.Text = txtemail.Text + booking.Email;
                    txthouseno.Text = txthouseno.Text + booking.HouseNo;
                    txtstreet.Text = txtstreet.Text + booking.Street;
                    txtpostcode.Text = txtpostcode.Text + booking.Postcode;
                    txttown.Text = txttown.Text + booking.Town;
                    txtcounty.Text = txtcounty.Text + booking.County;
                    txtcontactno.Text = txtcontactno.Text + booking.ContactNo;

                    //Holiday Values
                    txtHolidayId.Text = txtHolidayId.Text + booking.HolidayId;
                    txthname.Text = txthname.Text + booking.HotelName;
                    txtl.Text = txtl.Text + booking.Location;
                    txtbf.Text = txtbf.Text + booking.BookFrom;
                    txtbt.Text = txtbt.Text + booking.BookTo;
                    txtcit.Text = txtcit.Text + booking.CheckInTime;
                    txtcot.Text = txtcot.Text + booking.CheckOutTime;
                    txtnorb.Text = txtnorb.Text + booking.NoOfRoomsBooked;
                    txtrt.Text = txtrt.Text + booking.RoomType;
                    txtrs.Text = txtrs.Text + booking.RoomServices;
                    txtpark.Text = txtpark.Text + booking.Parking;
                    txtpet.Text = txtpet.Text + booking.Pet;

                    //TravelInfo Values
                    txtTravelInfoId.Text = txtTravelInfoId.Text + booking.TravelInfoId;
                    txttf.Text = txttf.Text + booking.TravellingFrom;
                    txtd.Text = txtd.Text + booking.Destination;
                    txtf.Text = txtf.Text + booking.Fare;
                    txtti.Text = txtti.Text + booking.TravelInsurance;
                    txtifi.Text = txtifi.Text + booking.InFlightMeals;
                    txtla.Text = txtla.Text + booking.LuggageAllowance;
                    txtel.Text = txtel.Text + booking.ExtraLuggage;
                    txtch.Text = txtch.Text + booking.CarHire;
                    txtrtrans.Text = txtrtrans.Text + booking.ReturnTransfer;
                }

                MessageBox.Show("XML has been imported");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }

如果有人知道我哪里出了问题或者我需要添加/更改什么,请告诉我:)

非常感谢, 10gez10

【问题讨论】:

  • 出现什么样的错误?您正在设置相同的属性,例如 foreach 循环中的 txtCustomerId.Text,这看起来很奇怪。
  • 我已经尝试捕获 xml 异常,我得到的错误是这个 - imgur.com/wbqeBwy。重复相同文本框的原因是语法 xml.linq 如果未声明两次则抛出。不知道为什么,但你
  • @10gez10 - 你能分享你的 XML 吗?没有这个就很难回答。

标签: c# xml tags descendant


【解决方案1】:

你有几个问题:

  1. 首先,您的数据元素不是booking 元素的直接子元素,还有中间元素<Customer><Holiday><TravelInfo>。因此你需要做类似的事情

            var query = from booking in doc.Descendants("Booking")
                        let customer = booking.Element("Customer")
                        let holiday = booking.Element("Holiday")
                        let travelInfo = booking.Element("TravelInfo")
                        select new
                        {
                            //Customer Elements
                            CustomerId = customer.Element("CustomerId").Value,
                            Title = customer.Element("Title").Value,
                            HolidayId = holiday.Element("HolidayId").Value,
                            TravelInfoId = travelInfo.Element("TravelInfoId").Value,
                        }
    
  2. 其次,有几个元素拼写错误:

    • CheckOutTime 应该是 CheckoutTime
    • In-FlightMeals 应该是 InFlightMeals。
    • CarHire 应该是 CareHire(是的,“CareHire”就是 XML 中的内容。)

    因此,当您执行(例如)Element("In-FlightMeals").Value 时,Element() 将返回 null,因此您会收到 null 引用异常并且您的代码被中止。

  3. 第三,元素BookTo完全缺失,所以BookTo = holiday.Element("BookTo").Value产生空引用异常。

更一般地说,我不推荐这种编码方法。如果缺少任何 XML 元素,您的查询将引发异常,因为 element.Element("name") 将为空。更糟糕的是,Visual Studio 似乎没有报告发生空引用的准确行号,而是给出了 select new 语句的行号。而且(至少在我的版本中),也无法进入匿名类型的构造函数。这使得调试几乎不可能。

相反,跳过中间匿名类型并以更直接、更传统的方式做事:

            foreach (var booking in doc.Descendants("Booking"))
            {
                var customer = booking.Element("Customer");
                var holiday = booking.Element("Holiday");
                var travelInfo = booking.Element("TravelInfo");

                XElement element;

                if (customer != null)
                {
                    if ((element = customer.Element("CustomerId")) != null)
                        txtCustomerId.Text = txtCustomerId.Text + element.Value;
                }
                // And so on.
            }

【讨论】:

  • 谢谢你的朋友,我阅读了你的反馈,将它从匿名类型更改为建议的 foreach 循环构造函数,它适用于所有三个后代以及检查拼写错误等。这个线程可以关闭:)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-11
  • 1970-01-01
  • 1970-01-01
  • 2020-12-18
  • 1970-01-01
相关资源
最近更新 更多