2016-11-30 2 views
0

Meine XML-Antwort sieht wie folgt aus:XML Antwort auf Linq

"<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>" 

Und ich habe diese Linq für diese Reaktion ist wie folgt:

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; 

bekomme ich keine Fehler und weder jede Ausnahme, aber die Anzahl der zurückgegebenen Hotels ist 0. Ich bin ein Anfänger bei Linq. Jede Hilfe wird sehr geschätzt, und es war 7 Stunden geradeaus, ich suche nach Hilfe und versuche, es zu erledigen. Jetzt fühle ich die Sackgasse.

Vielen Dank im Voraus.

Antwort

0

Es gibt ein paar Probleme mit dem Code geschrieben.

Das erste Problem ist, dass der Code nicht für den Namespace zu <HotelResult> zugewiesen ist Konto. Der Namespace ist http://wwww.juniper.es/webservice/2007/ und wird vom Element <HotelAvailResponse> geerbt. Sie können den Namespace als xmlns Attribut sehen:

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

Dies ist der Grund, warum Ihre LINQ-Abfrage nichts zurückkehr - es ist für <HotelAvailResponse> mit dem XML-Namespace suchen http://schemas.xmlsoap.org/soap/envelope, und dass der Knoten nicht existiert, so dass Sie eine bekommen leere Sammlung. Jedes Mal gibt es einen Aufruf zu Descendants oder Element, muss der Namespace enthalten sein (das heißt, ns + "ElementName").

Das zweite Problem ist nicht ohne weiteres ersichtlich, bis acutally der Code ausgeführt wird, aber die folgende Erklärung

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

führt in <HotelOption> und <Board> nur einmal erscheinen (das heißt, eine Liste von 1) statt zweimal. Die <price> Informationen und <TotalFixAmounts> korrekt ausgefüllt - ich bin mir nicht ganz sicher, warum, aber es kann mit der verschachtelten Liste für <TotalFixAmounts> zu tun hat. Dies ist leicht fixiert, indem der Auswahl zu <HotelOption> ändern, wie folgt aus:

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

Jetzt ho wird eine Sammlung von <HotelOption> Knoten und ihre Kinder, werden beide verarbeitet werden und die verschachtelte Liste wird auch verarbeitet werden.

Weiter gibt es ein paar Probleme mit Ihrer LINQ-Anweisung, die NULL-Verweise Ausnahmen (vorausgesetzt, die Namespace-Ausgabe korrigiert) werfen. Diese sind:

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

ho ist die Sammlung aller <HotelOptions> Knoten und ihre Kinder - aber <Board> ist ein Kind von <HotelOption>, was an sich ist ein Kind von <HotelOptions>. Wenn die Arbeit mit XML Denken Sie daran, in der Natur hierarchisch ist - .Element(elementName) das erste Element mit diesem Namen, die ein Kind ist (nicht ein großes Kind oder weiter unten) zugreifen des übergeordneten Elements.Eine recht einfache Lösung ist <HotelOption> in die Erklärung hinzuzufügen:

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

Ein ähnliches Problem tritt hier:

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

pr ist die Sammlung von <Prices> Knoten, aber die Elemente in der select Anweisung verwiesen wird, sind Kinder von <Price>, nicht <Prices>. Element(elementName) wird der erste untergeordnete Knoten des übergeordneten Elements erhalten, und <Prices> hat keine anderen Kinder als <Price>.

Schließlich gibt es kein <Amount> Element, das ein Kind von <TotalFixAmounts> ist, so dass die folgende Zeile wird auch eine NULL-Verweis Ausnahme auslösen:

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

Anstelle der beiden ternären Operatoren, die Sie verwenden, würde ich empfehlen mit (string) - die explizite Besetzung wird sicher mit fehlenden Elementen oder Attributen umgehen. Wenn das Element oder Attribut fehlt, wird der Code nicht fehlschlagen, es wird einfach keinen Wert für diese Eigenschaft haben.

Also, das setzen alle zusammen Sie diese:

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(); 

Beachten Sie, dass jede Bezugnahme auf Descendants oder Element den Namespace ns in ihm hat.