2016-11-30 46 views
0

我的XML響應如下所示: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小時,我正在尋求幫助,並試圖完成它。現在我感到死路一條。

在此先感謝。

回答

0

您的發佈代碼有幾個問題。

第一個問題是代碼沒有考慮分配給<HotelResult>的命名空間。命名空間是http://wwww.juniper.es/webservice/2007/,並且從<HotelAvailResponse>元素繼承。你可以看到這個名字空間作爲一個xmlns屬性:

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

這是您的LINQ查詢不返回任何東西的原因 - 它尋找<HotelAvailResponse>與XML命名空間http://schemas.xmlsoap.org/soap/envelope,並在該節點不存在,那麼你會得到一個空集合。每次呼叫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>一個孩子,這本身就是一個<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>一個孩子,所以下面一行也將拋出一個空引用異常:

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