2014-02-06 3 views
0

У меня есть входящий поток XML из ответа веб-службы, которая выглядит как такСинтаксический XML с VB.NET с LINQ к XML

<?xml version="1.0" encoding="utf-16"?> 
<HotelPropertyDescriptionRS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" TimeStamp="2013-12-30T18:49:36" Version="1.14.1"> 
    <Success xmlns="http://webservices.sabre.com/sabreXML/2003/07" /> 
    <RoomStay xmlns="http://webservices.sabre.com/sabreXML/2003/07"> 
    <RoomRates> 
     <RoomRate GuaranteeSurchargeRequired="G" IATACharacteristicIdentification="BGGO00" IATAProductIdentification="BLOOMBERG" RPH="001"> 
     <AdditionalInfo> 
      <CancelPolicy Numeric="06" /> 
      <Commission NonCommission="true">NON COMMISSIONABLE</Commission> 
      <Text>BLOOMBERG LP, 0.0 KM, INCLUDES BREAKFAST, INTERNET, WIFI, SEE</Text> 
      <Text>RATE RULES DELUXE ROOM, GUEST ROOM, 1 KING OR 2 TWIN/SINGLE BE</Text> 
     </AdditionalInfo> 
     <Rates> 
      <Rate Amount="66.600" CurrencyCode="KWD"> 
      <AdditionalGuestAmounts> 
       <AdditionalGuestAmount MaxExtraPersonsAllowed="0"> 
       <Charges ExtraPerson="0" /> 
       </AdditionalGuestAmount> 
      </AdditionalGuestAmounts> 
      <HotelTotalPricing Amount="76.590"> 
       <Disclaimer>INCLUDES TAXES AND SURCHARGES</Disclaimer> 
       <TotalSurcharges Amount="9.990" /> 
      </HotelTotalPricing> 
      </Rate> 
     </Rates> 
     </RoomRate> 
.... 

(там будет много значений RoomRate вернулся. Я создал класс для держать значения мне нужно разобрать из указанных XML, который выглядит так

Namespace Classes.Models 
    Public Class RoomRate 
     Public Property Rate() As String 
     Public Property Surcharge() As String 
     Public Property TotalPrice() As String 
     Public Property CurrencyCode() As String 
     Public Property CancellationPolicy() As String 
     Public Property Disclaimer() As String 
     Public Property Text() As List(Of String) 
     Public Property Commission() As String 
     Public Property GuaranteeSurchargeRequired() As String 
     Public Property IATACharacteristicIdentification() As String 
     Public Property IATAProductIdentification() As String 
     Public Property RPH() As String 
    End Class 
End Namespace 

Теперь я не ищу кого-то, чтобы написать весь код для меня, я еще ищу идеи, на которых было бы наиболее эффективный способ проанализировать это в моем классе. Я могу использовать XPathDocument и XPathNavigation & классы XPathNodeIterator для этого (не на 100% уверены, как они работают), но есть ли лучший способ выполнить эту задачу?

EDIT

Я пришел с этим до сих пор, которые должны получить мне первые атрибуты в RoomRate элемент

Return From el As XElement In _xDoc...<RoomRate> 
       Select New RoomRate With { _ 
        .GuaranteeSurchargeRequired = el...<RoomRate>[email protected], _ 
        .IATACharacteristicIdentification = el...<RoomRate>[email protected], _ 
        .IATAProductIdentification = el...<RoomRate>[email protected], _ 
        .RPH = el...<RoomRate>[email protected]} 

Теперь как бы я пройти, чтобы получить сказать, политику отмены, стоимость номера и другие атрибуты/элементы в этом коде, который я предоставил? Извините за так много вопросов, я действительно хочу научиться этому правильному пути и быть в состоянии сделать это правильно.

EDIT # 2

Я думаю, что я нахожусь на правильном пути здесь:

Return From el As XElement In _xDoc...<RoomRate> 
      Select New RoomRate With { _ 
       .GuaranteeSurchargeRequired = [email protected], _ 
       .IATACharacteristicIdentification = [email protected], _ 
       .IATAProductIdentification = [email protected], _ 
       .RPH = [email protected], _ 
       .CancellationPolicy = el...<AdditionalInfo>...<CancellationPolicy>[email protected], _ 
       .Commission = el...<AdditionalInfo>...<Commission>[email protected]} 

Может кто-то дайте мне знать, если я нахожусь на правильном пути для достижения этого?

EDIT 3

Я изменил код для этого

For Each n As XElement In _xDoc.Elements("RoomRate") 
        _rates.Add(New RoomRate With { _ 
           .GuaranteeSurchargeRequired = n.Attribute("GuarateeSurchargeRequired").Value, _ 
           .IATACharacteristicIdentification = n.Attribute("IATACharacteristicIdentification").Value, _ 
           .IATAProductIdentification = n.Attribute("IATAProductIdentification").Value, _ 
           .RPH = n.Attribute("RPH")}) 
       Next 

И пока я больше не получаю какие-либо ошибки, но я не получаю никаких результатов не дал, а также.

EDIT 4 Я сделал следующие изменения т моего кода, который должен возвращать IEnumerable (Of RoomRate), но она не будет возвращением ничего (это основано на XML фрагменте я написал выше)

Dim rates = From rate In _xDoc.Descendants("RoomRate") 
       Select New RoomRate With { _ 
        .GuaranteeSurchargeRequired = rate.Attribute("GuaranteeSurchargeRequired").Value, _ 
        .IATACharacteristicIdentification = rate.Attribute("IATACharacteristicIdentification").Value, _ 
        .IATAProductIdentification = rate.Attribute("IATAProductIdentification").Value, _ 
        .RPH = rate.Attribute("RPH").Value} 

Похоже, это должно сработать, что я делаю неправильно здесь?

EDIT # 5 @Neolisk Я сделал мои изменения так, как вы предложили, теперь он выглядит так

For Each n As XElement In _xDoc.Descendants("RoomRate") 
    rate = New RoomRate() 
    rate.GuaranteeSurchargeRequired = n.Attribute("GuaranteeSurchargeRequired").Value 
    rate.IATACharacteristicIdentification = n.Attribute("IATACharacteristicIdentification").Value 
    rate.IATAProductIdentification = n.Attribute("IATAProductIdentification") 
    _rates.Add(rate) 
Next 
Return _rates 

Но он никогда не переходит в петлю, он идет прямо к Возратиться _rates

EDIT # 6

Хорошо я получил его заселять первые 3 атрибуты RoomRate элемент, как этот

Dim rate As RoomRate 
Dim ns As XNamespace = "http://webservices.sabre.com/sabreXML/2003/07" 
Dim rate As RoomRate 
For Each n As XElement In _xDoc.Descendants(ns + "RoomRate") 
    rate = New RoomRate() 
    rate.GuaranteeSurchargeRequired = n.Attribute("GuaranteeSurchargeRequired").Value 
    rate.IATACharacteristicIdentification = n.Attribute("IATACharacteristicIdentification").Value 
    rate.IATAProductIdentification = n.Attribute("IATAProductIdentification").Value 
    rate.RPH = n.Attribute("RPH").Value 

    _rates.Add(rate) 
Next 

Теперь, когда я пытаюсь пройти через остальную часть документа, я стараюсь и получить значение CancelPolicy как так

Dim rate As RoomRate 
Dim ns As XNamespace = "http://webservices.sabre.com/sabreXML/2003/07" 
Dim rate As RoomRate 
For Each n As XElement In _xDoc.Descendants(ns + "RoomRate") 
    rate = New RoomRate() 
    rate.GuaranteeSurchargeRequired = n.Attribute("GuaranteeSurchargeRequired").Value 
    rate.IATACharacteristicIdentification = n.Attribute("IATACharacteristicIdentification").Value 
    rate.IATAProductIdentification = n.Attribute("IATAProductIdentification").Value 
    rate.RPH = n.Attribute("RPH").Value 
    rate.CancellationPolicy = n.Element("AdditionalInfo").Element("CancelPolicy").Attribute("Numeric").Value 

    _rates.Add(rate) 
Next 

Но добавив, что последняя строка вызывает NullReferenceException. Как мне теперь пройти через XML?

+0

Какую версию .NET вы используете? LINQ to XML намного проще, чем XPathDocument, особенно в VB.NET, где вы можете использовать XML-литералы inline. –

+0

Я использую .NET 4.0 – PsychoCoder

+1

Затем используйте LINQ to XML и игнорируйте XPathDocument и XmlDocument. –

ответ

1

Got мой вопрос решен с этим кодом

Public Function ParseRates() As IEnumerable(Of RoomRate) 
    Try 
     Dim ns As XNamespace = "http://webservices.sabre.com/sabreXML/2003/07" 
     Dim rate As RoomRate 
     For Each n As XElement In _xDoc.Descendants(ns + "RoomRate") 
      _rates.Add(New RoomRate With { _ 
         .GuaranteeSurchargeRequired = n.Attribute("GuaranteeSurchargeRequired").Value, _ 
         .IATACharacteristicIdentification = n.Attribute("IATACharacteristicIdentification").Value, _ 
         .IATAProductIdentification = n.Attribute("IATAProductIdentification").Value, _ 
         .RPH = n.Attribute("RPH").Value, _ 
         .CancellationPolicy = n.Element(ns + "AdditionalInfo").Element(ns + "CancelPolicy").Attribute("Numeric").Value, _ 
         .Commission = n.Element(ns + "AdditionalInfo").Element(ns + "Commission").Attribute("NonCommission").Value, _ 
         .Rate = n.Element(ns + "Rates").Element(ns + "Rate").Attribute("Amount").Value, _ 
         .CurrencyCode = n.Element(ns + "Rates").Element(ns + "Rate").Attribute("CurrencyCode").Value, 
         .TotalPrice = n.Element(ns + "Rates").Element(ns + "Rate").Element(ns + "HotelTotalPricing").Attribute("Amount").Value, _ 
         .Disclaimer = n.Element(ns + "Rates").Element(ns + "Rate").Element(ns + "HotelTotalPricing").Element(ns + "Disclaimer").Value, _ 
         .Surcharge = n.Element(ns + "Rates").Element(ns + "Rate").Element(ns + "HotelTotalPricing").Element(ns + "TotalSurcharges").Attribute("Amount").Value}) 
     Next 
     Return _rates 
    Catch ex As Exception 
     ErrorMessage = ex.Message 
     Return Nothing 
    End Try 
End Function 

Может быть, когда-нибудь я найду более эффективный способ сделать это

0

Если вы никогда не имели дело с LINQ к XML, вы можете найти себе изо всех сил немного в начале, но это должно помочь вам попасть туда быстрее:

Dim xml As XDocument = XDocument.Parse("...") 'or XDocument.Load("...") 

Вы также можете присвоить весь XML (или его часть) в переменную AS IS, чтобы проверить вашу концепцию, то это 100% действительный синтаксис в VB10 + (~ .NET 4.0+):

Dim xml As XDocument = <?xml version="1.0" encoding="utf-16"?> 
         <RoomRates> 
         <RoomRate> 
          <AdditionalInfo> 
          <Text>BLOOMBERG LP, 0.0 KM</Text> 
          </AdditionalInfo> 
          <Rates> 
          <Rate Amount="66.600" CurrencyCode="KWD"></Rate> 
          </Rates> 
         </RoomRate> 
         </RoomRates> 

После этого, вот что вы можете сделать:

Dim ns As XNamespace = "http://webservices.sabre.com/sabreXML/2003/07" 
Dim roomRate As XElement = xml.Descendants(ns + "RoomRate").First 

Dim additionalInfoText As String = roomRate.Descendants(ns + "Text").First 

Теперь вы можете проверить как roomRate, так и additionalInfoText в отладчике, чтобы узнать, как это работает.

В случае сомнений относительно функциональности XDocument/XElement, пожалуйста, ознакомьтесь с соответствующими статьями MSDN.

+0

Ты прав, я борюсь с этим. Это сложный XML-файл, и я пытаюсь получить атрибуты и элементы в своем классе. Как только я получу 1, я смогу выяснить, как пройти и получить все. Любая помощь от кого? – PsychoCoder

+0

@PsychoCoder: Выше ничего не помогло? Если у вас есть вопрос, не стесняйтесь спрашивать. Без вопроса я не могу вам помочь. Чтобы сделать вышеприведенный код, я вставил ваш XML как текст в файл кода и добавил отсутствующие конечные теги (чтобы сделать его действительным). Я имею в виду, что это не просто код, это фактический код для ВАШИХ данных, чтобы продемонстрировать механизм извлечения данных с использованием LINQ-to-XML. Как вы можете себе представить, я тестировал его для работы в Visual Studio перед публикацией здесь. – Neolisk

+0

проверить мое редактирование выше, может быть, это прояснит все, что у меня с проблемами :) – PsychoCoder

Смежные вопросы