2014-12-29 4 views
0

У меня проблемы с моим приложением C#. Он может только получить атрибуты первого узла, а затем не может получить атрибуты следующего узла.xml атрибуты не обнаружены

XML-в этом формате ..

<ALLPRODUCTS> 
    <PRODUCT ITEM="1"> 
    <QUANTITY>5</QUANTITY> 
    </PRODUCT> 
    <PRODUCT ITEM="2"> 
    <QUANTITY>6</QUANTITY> 
    </PRODUCT>.... 

Приложение получает первый номер продукта, как 1 и имеет величину 5 ... но после того, что он просто дает количества и говорит пункт число - null. Вот код im, использующий ...

while (reader.Read()) 
     { 
      if (reader.Name.Equals("PRODUCT")) 
      { 
       String id; 
       String qty;     

       try 
       { 

        id = reader.GetAttribute("ITEM"); 
        reader.ReadToFollowing("QUANTITY"); 
        qty = reader.ReadInnerXml(); 

        if (qty.Equals("0")) 
        { 
         oos++; 
        } 
        else 
        { 
         inStock++; 
        } 

        status.Refresh(); 
        stockLevelList.Add(id, qty); 

       } 
       catch (Exception e) 
       { 
        MessageBox.Show(e.Message, e.Source, MessageBoxButtons.OK, MessageBoxIcon.Error); 
       } 

      } 

Может кто-нибудь предложить, почему продукты после первого получают null как id?

+0

Если ваш XML не является ОГРОМНЫМ (т. Е. Больше, чем 25 Мб), вам, скорее всего, лучше использовать методы DOM, такие как XmlDocument и SelectNodes для такого рода операций. –

+0

Я думаю, что вы хотите сделать 'reader.MoveToNextAttribute()', а затем проверить имя, чтобы увидеть, является ли это 'ITEM'. Если это так, вы можете вызвать 'reader.Value', чтобы получить его. Для этого, однако, я бы, вероятно, просто использовал сериализацию XML с некоторыми POCO вместо того, чтобы сражаться с XML Reader. Это может быть довольно PITA, чтобы развиваться против. – TyCobb

+0

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

ответ

1

Вы не проверяете, находится ли читатель в начале элемента. Ваш код взрывается, потому что он пытается обработать на основе конечного элемента PRODUCT.

Добавить эту проверку сразу после заявления if, где он проверяет «ПРОДУКТ».

if (reader.Name.Equals("PRODUCT")) 
{ 
    if (!reader.IsStartElement()) 
     continue; 

    // Your normal processing code here. 
} 

Это то, что делает использование XmlReader несколько боли. Он пересекает каждый элемент, что означает, что вам нужно обратить внимание на то, где он может быть. Первый раз, через Начальный элемент. Вы обрабатываете и все хорошо, но затем он достигает элемента </PRODUCT>, который по-прежнему называется "PRODUCT", и именно там он разваливается.

Ниже представлен заказ, основанный на вашем коде перемещения reader вперед.

  • reader.Read() переходит к первому элементу: ALLPRODUCTS
  • Не то, что вы искали так reader.Read() снова, и это находит тип узла Whitespace, потому что нет никакого внутреннего текста.
  • reader.Read() переехал в PRODUCT
  • Вы получаете атрибут, а затем сказать ему, чтобы читать QUANTITY. (Обратите внимание, что вы не можете вернуться. Вопросы для заказа)
  • reader.Read() переходит к следующему элементу PRODUCT. Это не <PRODUCT>. Это </PRODUCT>.
  • Ваш код Сейчас начинается большинство выше процесс снова, но терпит неудачу, потому что не было на <PRODUCT>

EDIT: Также Becareful с XmlReader. XML не обязательно должен быть действительным для того, чтобы XmlReader работал до определенной точки. Он только выдает ошибку, когда она достигает проблемы, и вы, возможно, уже обработали несколько сотен узлов в этой точке.

+0

@FearghalConn Я сразу же нашел проблему, наведя курсор мыши на 'reader', чтобы проверить значения после каждого 'Read()'. Он сказал «EndElement». Отладчик - ваш друг;) – TyCobb

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