2013-05-13 3 views
0

Я получаю строку XML из веб-службы и разбираю ее, чтобы получить несколько значений, которые мне нужно сохранить. Я помещаю строку в XmlDocument и использую XmlNodeReader для анализа имени элемента и захвата значения.Как разобрать несколько элементов для определенного значения

Это хорошо обособленно, когда значение я после того, как называется, такие как тип, идентификатор или источника, в этом фрагменте:

<WebResult> 
    <Header> 
     <Type>Success</Type> 
     <ID>52347</ID> 
    </Header> 
    <Source>Global</Source> 
    <ReturnItems> 
    <ReturnItem> 
     <DataName>SaleID</DataName> 
     <DataValue>CO12345</DataValue> 
    </ReturnItem> 
    <ReturnItem> 
     <DataName>ProductID</DataName> 
     <DataValue>XY000001</DataValue> 
    </ReturnItem> 
    </ReturnItems> 
</WebResult> 

Однако, я не уверен, что лучший путь к пикап SalesID-х Значение «DataValue» CO12345 в этом примере. (Схема XML намного больше)

Я мог разобрать строку для символов SaleID + x, но это сломалось бы, если веб-сервис изменился, и я полагаюсь на строковые позиции. Я бы предпочел не сериализоваться в класс, поскольку кажется, что должен быть простой способ сделать это. (который мне не хватает!)

+0

Я отредактировал ваш заголовок. Пожалуйста, смотрите: «Если вопросы включают« теги »в их названиях?] (Http://meta.stackexchange.com/questions/19190/), где консенсус« нет, они не должны ». –

ответ

1

Это очень легко с LINQ to XML, если вы в состоянии (или хотите) его использовать.

' XDocument.Parse will load XML from a string 
' Use XDocument.Load to load it from a file 
Dim xDoc As XDocument = XDocument.Parse(xmlString) 

Dim salesID = (From x In xDoc.Descendants("ReturnItem") 
       Where x.Element("DataName").Value = "SaleID" 
       Select x.Element("DataValue").Value).FirstOrDefault() 

Что выше фрагмент кода первым получает все элементы «ReturnItem» (и их детей) в xDoc.

Далее он фильтрует его на элементах «DataName», у которых в качестве значения используется SalesID.

Затем он выбирает соответствующее значение элемента «DataValue».

FirstOrDefault возвращает первый элемент, который соответствует (или значение по умолчанию, если ничего не найдено). Без FirstOrDefault() вы получите коллекцию совпадающих результатов, которую вы могли бы затем перебрать.

Вышеприведенный пример довольно простой, но LINQ to XML очень мощный, и я предпочитаю его при работе с XML.

отредактирован ADD NON-LinQ ПОДХОД

Вот способ сделать выше, используя XmlDocument и XPath syntax:

Dim xmlDoc As New XmlDocument() 
' Use LoadXML to load from a string; if from a file use Load 
xmlDoc.LoadXml(xmlString) 

Dim SaleID As String 

Dim ReturnItems As XmlNodeList = xmlDoc.SelectNodes("/WebResult/ReturnItems/ReturnItem") 

For Each Item As XmlNode In ReturnItems 
    If Item.SelectSingleNode("DataName").InnerText = "SaleID" Then 
     SaleID = Item.SelectSingleNode("DataValue").InnerText 
    End If 
Next 

выше фрагмент кода загружает строку XML в XmlDocument. Затем он выбирает все узлы, которые соответствуют выражению XPath «/ WebResult/ReturnItems/ReturnItem» (т. Е. Он захватывает все узлы ReturnItem и их дочерние элементы).

Далее он выполняет итерацию через коллекцию, и для каждого узла ReturnItem он проверяет, равен ли узел DataName «SaleID», а затем он присваивает значение узла DataValue строке SaleID ,

Это, опять же, тривиальный пример. Если у вас есть несколько узлов SaleID в XML, вам нужно будет поместить значения в список или другую коллекцию, иначе приведенный выше код даст вам только последний.

XPath очень мощный, а богатая поддержка XML и XPath входит в состав .NET Framework с 1.0.

Преимущество в том, что если формат сообщения когда-либо изменяется, вам нужно будет обновить ваши запросы XPath, а не выяснять, как разбирать новый формат.

+0

Спасибо Тим. Linq - это, безусловно, путь, но по причинам, не зависящим от нашего контроля, мы придерживаемся NET Framework 2.0 для этого проекта. (Framework несовместим с Linq без каких-либо хаков.) – SSJON

+0

@SSJON - Взгляните на запросы XmlDocument и XPath. Я привел тривиальный пример выше, чтобы дать вам базовую идею. – Tim

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