powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Странное поведение XmlReader
12 сообщений из 12, страница 1 из 1
Странное поведение XmlReader
    #38571537
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Столкнулся со странностью, которую не могу объяснить.
Есть код
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
using (XmlReader reader = XmlReader.Create(input))
{
	for (reader.MoveToContent(); reader.Read(); )
		if (reader.NodeType == XmlNodeType.Element)
			switch (reader.Name)
			{
				case "row":
					break;

				case "c":
					string strValue = reader.ReadElementString();
					break;
			}
}


который читает XML файл
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
<row r="2" spans="1:20" ht="35.1" customHeight="1" x14ac:dyDescent="0.2">
<c r="A2" s="9"/>
<c r="B2" s="9"/>
<c r="C2" s="9"/>
<c r="D2" s="9"/>
<c r="E2" s="9"/>
<c r="F2" s="9"/>
<c r="G2" s="9"/>
<c r="H2" s="9"/>
<c r="I2" s="1" t="s"><v>7</v></c>
<c r="J2" s="1" t="s"><v>8</v></c>
<c r="K2" s="1" t="s"><v>9</v></c>
<c r="L2" s="1" t="s"><v>10</v></c>
<c r="M2" s="1" t="s"><v>11</v></c>
<c r="N2" s="1" t="s"><v>12</v></c>
<c r="O2" s="1" t="s"><v>13</v></c>
<c r="P2" s="1" t="s"><v>14</v></c>
<c r="Q2" s="1" t="s"><v>15</v></c>
<c r="R2" s="1" t="s"><v>16</v></c>
<c r="S2" s="1" t="s"><v>17</v></c>
<c r="T2" s="1" t="s"><v>18</v></c>
</row>


Так вот, reader читает элементы "c" с пропусками. Т.е.
<c r="A2" s="9"/>
<c r="C2" s="9"/>
<c r="F2" s="9"/>
не подряд. Почему, не могу понять. В отладчике ровно так - перескакивает через записи.
Дойдя до
<c r="I2" s="1" t="s"><v>7</v></c>
снова читает все подряд, так как нужно.
Кто сталкивался?
...
Рейтинг: 0 / 0
Странное поведение XmlReader
    #38571595
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Либо вы что-то не привели в коде, либо смотрите что-то не то:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
using (var sr = new StringReader(Properties.Resources.XData))
using (var reader = XmlReader.Create(sr))
{
  for (reader.MoveToContent(); reader.Read(); )
    if (reader.NodeType == XmlNodeType.Element)
      switch (reader.Name)
      {
        case "row":
          break;

        case "c":
          reader.MoveToAttribute("r");
          reader.ReadAttributeValue();
          var info = string.Format("{0} {1}", ((IXmlLineInfo)reader).LineNumber, reader.Value);
          reader.MoveToElement();
          Console.WriteLine("{0} {1}", info, reader.ReadElementString());
          break;
      }
}


Вывод:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
2 A2
3 B2
4 C2
5 D2
6 E2
7 F2
8 G2
9 H2
10 I2 7
11 J2 8
12 K2 9
13 L2 10
14 M2 11
15 N2 12
16 O2 13
17 P2 14
18 Q2 15
19 R2 16
20 S2 17
21 T2 18
...
Рейтинг: 0 / 0
Странное поведение XmlReader
    #38571633
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код конечно указан не весь. Вот как было
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
                            case "c":
                                span = reader.GetAttribute("s");
                                type = reader.GetAttribute("t");
                                reff = reader.GetAttribute("r");

                                reader.MoveToElement();
                                string strValue = reader.ReadElementString();
                                ...



Переделал с учетом вашего предложения.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
                            case "c":
                                reader.MoveToAttribute("r");
                                reader.ReadAttributeValue();
                                reff = reader.Value.ToString();

                                reader.MoveToAttribute("s");
                                reader.ReadAttributeValue();
                                span = reader.Value.ToString();

                                reader.MoveToAttribute("t");
                                reader.ReadAttributeValue();
                                type = reader.Value.ToString();

                                reader.MoveToElement();
                                string strValue = reader.ReadElementString();
                                ...



Только результат один. Отрицательный.
...
Рейтинг: 0 / 0
Странное поведение XmlReader
    #38571644
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Беда еще в том, что если подсунуть коду XML, то он читает его правильно.
Но если читать из Stream объекта FileUpload, то такое странное чтение.
...
Рейтинг: 0 / 0
Странное поведение XmlReader
    #38571762
Sergey S
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Как формируется XML?
Может проблема в этом?
т.е. предполагаю - что теги "с" - строятся по какому то условию, и перепутана буква латиница "с" и русская "с"
...
Рейтинг: 0 / 0
Странное поведение XmlReader
    #38571775
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sergey SКак формируется XML?
Может проблема в этом?
т.е. предполагаю - что теги "с" - строятся по какому то условию, и перепутана буква латиница "с" и русская "с"

Если бы... Только файл стандартнее некуда. Распакованный XML из Windows Excel 2007 (*.xlsx).
Впрочем могу приложить, можете сами убедиться, что там все нормально.

Не исключаю вариант, что взятый по отдельности он будет читаться без проблем.
Может эти косяки только у меня на компе.
...
Рейтинг: 0 / 0
Странное поведение XmlReader
    #38571905
petalvik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008,

на форуме приведён xml с разбиением на строки, а в файле содержимое записано в одну строку. То есть в первом случае между элементами присутствует XmlNodeType.Whitespace, а во втором случае - нет.
Это распространённая ошибка, не учитывать этот момент при ручном разборе xml. Я сам раньше часто на это напарывался.
...
Рейтинг: 0 / 0
Странное поведение XmlReader
    #38571914
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Опытным путем было установлено, что использование
Код: c#
1.
 reader.ReadElementString(); 

приводит к пропускам при чтении.
Отсюда следует, что нужно повнимательнее использовать эту функцию.
Всем спасибо!
Думаю, что далее разрулю косяк самостоятельно.
...
Рейтинг: 0 / 0
Странное поведение XmlReader
    #38571920
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petalvikна форуме приведён xml с разбиением на строки, а в файле содержимое записано в одну строку. То есть в первом случае между элементами присутствует XmlNodeType.Whitespace, а во втором случае - нет.
Это распространённая ошибка, не учитывать этот момент при ручном разборе xml. Я сам раньше часто на это напарывался.
Я бы согласился, но это косячит только в одном месте. Далее все работает как нужно.
Впрочем, похоже, что я нашел проблему (см выше).
...
Рейтинг: 0 / 0
Странное поведение XmlReader
    #38571925
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А теперь найдите 10 отличий в том примере xml, который был приведен в стартовом постинге, и в том, который в аттаче. Подсказка: форматирование разметки. Пробелы и переносы строк между узлами - это тоже узлы xml, и ридер движется по ним - если они есть - сообразно вашим командам.
Вот такое:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
using (var sr = new StringReader(Properties.Resources.XData))
using(var reader = XmlReader.Create(sr))
{
  for (reader.MoveToContent(); reader.Read(); )
  {
    if (reader.NodeType != XmlNodeType.Element) continue;
    Console.WriteLine(reader.GetAttribute("r"));
    reader.MoveToElement();
    Console.WriteLine(reader.GetAttribute("r"));
    reader.ReadElementString();
    Console.WriteLine(reader.GetAttribute("r"));
    Console.WriteLine("===============================");
  }
}


на исходном xml c переносом строк даст вот такой вывод:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
A2
A2

===============================
B2
B2

===============================
C2
C2

===============================
D2
D2

===============================
E2
E2

===============================
F2
F2

===============================
G2
G2

===============================
H2
H2

===============================
I2
I2

===============================
...
а на xml в одну строку даст вот такой вывод:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
A2
A2
B2
===============================
C2
C2
D2
===============================
E2
E2
F2
===============================
G2
G2
H2
===============================
I2
I2

===============================
J2
J2
...
Причина в том, что: http://msdn.microsoft.com/en-us/library/hd94a4xh(v=vs.110).aspx
This is a helper method for reading simple text-only elements. It calls MoveToContent to find the next content node and then parses its value as a simple string.
а XmlReader.MoveToContent, в свою очередь
Checks whether the current node is a content (non-white space text, CDATA, Element, EndElement, EntityReference, or EndEntity) node. If the node is not a content node, the reader skips ahead to the next content node or end of file. It skips over nodes of the following type: ProcessingInstruction, DocumentType, Comment, Whitespace, or SignificantWhitespace.
- в случае xml c переносами MoveToContent, неявно вызываемый при ReadElementString, перемещает ридер на пустой текстовый узел,т.к. это вполне себе нода. А в случае с форматированием в одну строку - на следующий элемент.
А если вы отформатируете ваш xml с отступами, то код будет рваться на ReadElementString c ошибкой XmlException: Unexpected node type Element. ReadElementString method can only be called on elements with simple or empty content - т.к. пробельные узлы плюс пустые узлы плюс разметка плюс текст - это уже не simple content (а только тэг и текст - simple).
И вывод из всего этого очень простой: не нужно парсить своими средствами. Получайте XmlDocument/XDocument, нужную инфу извлекайте из них.
...
Рейтинг: 0 / 0
Странное поведение XmlReader
    #38571957
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны и petalvik, большое спасибо, за то, что вывели на правильную дорогу из зарослей заблуждений.
Уж начал сомневаться в состоянии рассудка
...
Рейтинг: 0 / 0
Странное поведение XmlReader
    #38572071
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Переписал код с использованием XmlDocument и глюки исчезли.
Правда при использовании XmlReader-a можно было читать все элементы подряд,
а в XmlDocument приходится учитывать структуру вложенности элементов.
Вопрос исчерпан, тема закрыта.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Странное поведение XmlReader
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]