2016-11-30 69 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