簡體   English   中英

XML對Linq的響應

[英]XML Response to Linq

我的XML響應如下所示:

"<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<HotelAvailResponse xmlns="http://www.juniper.es/webservice/2007/">
<AvailabilityRS Url="http://xml.bookingengine.es"
TimeStamp="20130327T14:38:54.6916528+01:00"
IntCode="lCf65bPrG+x7VDLB0IquVNQgKloRA9+HOuhfHMj0BcE=">
<Results>
<HotelResult Code="7b0LYEzfsd0HH90sd" JPCode="JP003600" DestinationZone="39303" JPDCode="JPD000014">
<HotelInfo>
<Name>Hotel Test</Name>
<Description>A spacious, quiet, light and bright hotel, with a garden and fabulous views across the city.</Description>
<Images>
<Image>http://www.bookingengine.es/images/upload_p/hoteltest.jpeg</Image>
</Images>
<HotelCategory>1 1/2 Stars</HotelCategory>
<HotelType Type="SKI">Snow</HotelType>
<Address>c/tap</Address>
</HotelInfo>
<HotelOptions>
<HotelOption RatePlanCode="dcFZbKty1cJGKeRtgxIDGUZAprp1mua8ySl4iVIZ7NVKBF/PGk8lhZlN7Hcszjs2RwUR2Dxsrv5l0cZDORKz6frEmPdibqOyV2Jg4Dxz8/bF5gqPyQR8+z1LEu8LCVlS" Status="OK">
<Board Type="AD">Bed&amp;Breakfast</Board>
<Prices>
<Price Type="S" Currency="USD">
<TotalFixAmounts Gross="353.65" Nett="353.65">
<Service Amount="321.5"/>
<ServiceTaxes Included="true" Amount="32.15"/>
<Commissions Included="true" Amount="0"/>
<HandlingFees Included="true" Amount="0"/>
<Discount Amount="-0"/>
</TotalFixAmounts>
</Price>
</Prices>
<HotelRooms>
<HotelRoom Units="1" Source="1" AvailRooms="12">
<Name>Double Room</Name>
<RoomCategory Type="DBL">Double Standard</RoomCategory>
</HotelRoom>
<HotelRoom Units="1" Source="2" AvailRooms="45">
<Name>Single</Name>
<RoomCategory Type="SGL">Single Standard</RoomCategory>
</HotelRoom>
</HotelRooms>
</HotelOption>
<HotelOption RatePlanCode="dcFZbKty1cJGKeRtgxIDGUZAprp1mua8ySl4iVIZ7NVKBF/PGk8lhZlN7Hcszjs2RwUR2Dxsrv5l0cZDORKz6frEmPdibqOyV2Jg4Dxz8/bmoX041DU9+3D3nHCEB/6vYKbVtJR2qaHwW9VnnWl/KA==" Status="OK">
<Board Type="AD">Bed&amp;Breakfast</Board>
<Prices>
<Price Type="S" Currency="USD">
<TotalFixAmounts Gross="353.65" Nett="353.65">
<Service Amount="321.5"/>
<ServiceTaxes Included="true" Amount="32.15"/>
<Commissions Included="true" Amount="0"/>
<HandlingFees Included="true" Amount="0"/>
<Discount Amount="-0"/>
</TotalFixAmounts>
</Price>
</Prices>
<HotelRooms>
<HotelRoom Units="1" Source="1" AvailRooms="12">
<Name>Double Room</Name>
<RoomCategory Type="DBL">Double Standard</RoomCategory>
</HotelRoom>
<HotelRoom Units="1" Source="2" AvailRooms="11">
<Name>Double Room</Name>
<RoomCategory Type="DBL">Double Standard</RoomCategory>
</HotelRoom>
</HotelRooms>
<AdditionalElements>
<HotelOffers>
<HotelOffer>
<Name>Basic Discount 10%</Name>
</HotelOffer>
</HotelOffers>
</AdditionalElements>
</HotelOption>
</HotelOptions>
</HotelResult>
</Results>
</AvailabilityRS>
</HotelAvailResponse>
</soap:Body>
</soap:Envelope>"

我對此響應有此Linq,如下所示:

XNamespace ns = "http://schemas.xmlsoap.org/soap/envelope/";
var hotels = (from hotelData in data.Descendants(ns + "Envelope").Descendants(ns + "Body").Descendants("HotelAvailResponse").Descendants("HotelAvailResult").Descendants("Results").Descendants("HotelResult")

                      select new Hotel
                          {
                              Code = hotelData.Attribute("Code").Value,
                              JpCode =
                                  hotelData.Attributes().Any(x => x.Name == "JPCode")
                                      ? hotelData.Attribute("JPCode").Value
                                      : "",
                              DestinationZone =
                                  hotelData.Attribute("DestinationZone") != null
                                      ? hotelData.Attribute("DestinationZone").Value
                                      : string.Empty,
                              JpdCode = hotelData.Attribute("JPDCode").Value,
                              //HotelName = Convert.ToString(hotelData.Element("Item").Value),
                              //Rating = Convert.ToInt32(hotelData.Element("StarRating").Value),

                              HotelInfo = (from hi in hotelData.Descendants("HotelInfo")
                              select new HotelInfo
                                  {
                                      Name = hi.Element("Name").Value,
                                      Description = hi.Element("Description").Value,
                                      Image = (from img in hi.Descendants("Images") select new Imagez { Images = img.Element("Image").Value }).ToList(),
                                      HotelCategory = hi.Element("Name").Value,
                                      HotelType = hi.Element("Description").Value,
                                      Address = hi.Element("Description").Value,
                                  }
                                  ).ToList(),

                              HotelOptions = (from ho in hotelData.Descendants("HotelOptions")
                                                  select new HotelOptions()
                                                      {
                                                          HotelOption = ho.Element("HotelOption").Attribute("RatePlanCode").Value,
                                                          Board = ho.Element("Board").Attribute("Type").Value,
                                                          Prices = (from pr in ho.Descendants("Prices") select new Prices() { Price = pr.Element("Price").Value,
                                                          TotalFixAmounts = (from tfa in pr.Descendants("TotalFixAmounts") select new TotalFixAmounts() 
                                                          { Service = tfa.Element("Service").Attribute("Amount").Value,
                                                            ServiceTaxes = tfa.Element("ServiceTaxes").Attribute("Included").Value,
                                                            AmountServiceTaxes = tfa.Element("ServiceTaxes").Attribute("Amount").Value,
                                                            Commissions = tfa.Element("Commissions").Attribute("Included").Value,
                                                            AmountCommissions = tfa.Element("Commissions").Attribute("Amount").Value,
                                                            HandlingFees = tfa.Element("HandlingFees").Attribute("Included").Value,
                                                            AmountHandlingFees = tfa.Element("HandlingFees").Attribute("Amount").Value,
                                                            Discount = tfa.Element("Amount").Attribute("Included").Value,
                                                          }).ToList(),
                                                          }).ToList(),
                                                      }).ToList(),
                          }).ToList();
        return hotels;

我沒有錯誤,也沒有任何異常,但是返回的酒店數量為0。我是Linq的初學者。 任何幫助將不勝感激,並且已經連續7個小時了,我正在尋找幫助並嘗試將其完成。 現在我感到死胡同了。

提前致謝。

您發布的代碼存在一些問題。

第一個問題是代碼沒有考慮分配給<HotelResult>的名稱空間。 命名空間為http://wwww.juniper.es/webservice/2007/ ,並且繼承自<HotelAvailResponse>元素。 您可以將名稱空間視為xmlns屬性:

<HotelAvailResponse xmlns="http://www.juniper.es/webservice/2007/">

這就是您的LINQ查詢未返回任何內容的原因-它正在尋找具有XML命名空間http://schemas.xmlsoap.org/soap/envelope的 <HotelAvailResponse> ,並且該節點不存在,因此您得到一個空集合。 每次調用DescendantsElement ,都需要包含名稱空間(即ns + "ElementName" )。

在代碼正常運行之前,第二個問題並不明顯,但是下面的語句

HotelOptions = (from ho in hotelData.Descendants(ns + "HotelOption")

將導致<HotelOption><Board>僅出現一次(即列表1),而不出現兩次。 <price>信息和<TotalFixAmounts>正確填充-我不確定為什么,但可能與<TotalFixAmounts>的嵌套列表有關。 可以通過將選擇更改為<HotelOption>來輕松解決,如下所示:

HotelOption = (from ho in hotelData.Descendants("HotelOption")

現在ho將是<HotelOption>節點及其子節點的集合,這兩個節點都將被處理,並且嵌套列表也將被處理。

接下來,您的LINQ語句存在一些問題,這些問題將引發空引用異常(假設名稱空間問題已得到糾正)。 這些是:

Board = ho.Element("Board").Attribute("Type").Value;

ho是所有<HotelOptions>節點及其子級的集合-但是<Board><HotelOption>的子級,而<HotelOption>本身是<HotelOptions>的子<HotelOptions> 使用XML時,請記住它本質上是分層的.Element(elementName)將訪問具有該名稱的第一個元素,該元素是父元素的子元素(不是子元素,也不是子元素)。 一個相當簡單的解決方案是將<HotelOption>添加到語句中:

Board = ho.Element(ns + "HotelOption").Element(ns + "Board").Attribute("Type").Value;

這里發生類似的問題:

TotalFixAmounts = (from tfa in pr.Descendants("Prices") select new

pr<Prices>節點的集合,但是select語句中引用的元素是<Price>子元素,而不是<Prices>子元素。 Element(elementName)將獲取父元素的第一個子節點,並且<Prices>除了<Price>之外沒有其他子節點。

最后,沒有<Amount>元素是<TotalFixAmounts>的子元素,因此以下行還將引發null引用異常:

Discount = tfa.Element("Amount").Attribute("Included").Value;

代替您使用的兩個三元運算符,我建議使用(string) -顯式強制轉換將安全地處理缺少的元素或屬性。 如果缺少元素或屬性,則代碼不會失敗,它將對該屬性沒有任何值。

因此,將所有這些放在一起,您將得到:

XNamespace ns = "http://www.juniper.es/webservice/2007/";

var hotels = (from hotelData in data.Root.Descendants(ns + "HotelResult")
              select new Hotel
              {
                  Code = (string)hotelData.Attribute("Code"),
                  JpCode = (string)hotelData.Attribute("JPCode"),
                  DestinationZone = (string)hotelData.Attribute("DestinationZone"),
                  JpdCode = (string)hotelData.Attribute("JPDCode"),
                  HotelInfo = (from hi in hotelData.Descendants(ns + "HotelInfo")
                               select new HotelInfo
                               {
                                   Name = (string)hi.Element("Name"),
                                   Description = (string)hi.Element(ns + "Description"),
                                   Image = (from img in hi.Descendants(ns + "Images")
                                            select new Imagez
                                            {
                                                Images = (string)img.Element(ns + "Image")
                                            }).ToList(),
                                   HotelCategory = (string)hi.Element(ns + "Name"),
                                   HotelType = (string)hi.Element(ns + "Description"),
                                   Address = (string)hi.Element(ns + "Description"),
                               }).ToList(),
                  HotelOptions = (from ho in hotelData.Descendants(ns + "HotelOption")
                                  select new HotelOptions
                                  {
                                      HotelOption = ho.Attribute("RatePlanCode").Value,
                                      Board = ho.Element(ns + "Board").Attribute("Type").Value,
                                      Prices = (from pr in ho.Descendants(ns + "Prices")
                                                select new Price
                                                {
                                                    Price = (string)pr.Element(ns + "Price"),
                                                    TotalFixAmounts = (from tfa in pr.Descendants(ns + "Price").Descendants(ns + "TotalFixAmounts")
                                                                       select new TotalFixAmounts
                                                                       {
                                                                           Service = tfa.Element(ns + "Service").Attribute("Amount").Value,
                                                                           ServiceTaxes = tfa.Element(ns + "ServiceTaxes").Attribute("Included").Value,
                                                                           AmountServiceTaxes = tfa.Element(ns + "ServiceTaxes").Attribute("Amount").Value,
                                                                           Commissions = tfa.Element(ns + "Commissions").Attribute("Included").Value,
                                                                           AmountCommissions = tfa.Element(ns + "Commissions").Attribute("Amount").Value,
                                                                           HandlingFees = tfa.Element(ns + "HandlingFees").Attribute("Included").Value,
                                                                           AmountHandlingFees = tfa.Element(ns + "HandlingFees").Attribute("Amount").Value
                                                                       }).ToList(),
                                                }).ToList(),
                                  }).ToList(),
              }).ToList();

注意,對DescendantsElement每個引用都在其中包含名稱空間ns

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM