Member 10261487 Ответов: 2

Отсутствует корневой элемент Xmldocument. loadxml


Я пытаюсь прочитать поток, который находится в формате xml, чтобы получить определенные значения полей.

мой код:
using (var client = new TcpClient(host, port))
            {
                var reader = new StreamReader(client.GetStream());
                var writer = new StreamWriter(client.GetStream());
                writer.WriteLine(cmd);
                writer.Flush();
                var reply = reader.ReadLine(); 
                if (reply.Contains("202"))
                    {
                        while (reply.Length > 0)
                        {
                            reply = reader.ReadLine();
                            XmlDocument xmlDoc = new XmlDocument();
                            
                            String str = reply;
                            str = str.Replace("202 PLAY OK", "");
                            str = str.Replace("201 INFO OK", "");
                            xmlDoc.LoadXml(str);
                            string frame_path = "layer/producer";
                            //string fps_path = "layer/producer/fps";
                            var nodes_frame = xmlDoc.SelectNodes(frame_path);
                            //var nodes_fps = xmlDoc.SelectNodes(fps_path);

                            foreach (XmlNode childrenNode_frame in nodes_frame)
                            {
                                Console.WriteLine("Frames: " + childrenNode_frame.SelectSingleNode("//file-nb-frames").Value.ToString() + " Frame Rate: " + childrenNode_frame.SelectSingleNode("//fps").Value.ToString());
                            }
                           
                        }
                        
                    }
                    

                }
                
                Console.Read();
            }


Теперь я получаю исключение "корневой элемент отсутствует";

В моей консоли строка xml выглядит следующим образом:
<?xml version="1.0" encoding="utf-8"?>
<layer>
 <auto_delta>null</auto_delta>

 <frame-number>5236</frame-number>
 <nb_frames>45001</nb_frames>
 <frames-left>39765</frames-left>
 <frame-age>160</frame-age>
 <producer>
  <type>ffmpeg</type>
  <filename>media\JTV.AVI</filename>
  <width>720</width>
  <height>576</height>
  <progressive>true</progressive>
  <fps>25</fps>
  <loop>false</loop>
  <frame-number>5237</frame-number>
  <nb-frames>45001</nb-frames>
  <file-frame-number>0</file-frame-number>
  <file-nb-frames>45001</file-nb-frames>
 </producer>
 <background>
   <producer>
    <type>empty-producer</type>
   </producer>
 </background>
   <index>0</index>
</layer>


Что я уже пробовал:

Я пробовал использовать эту команду:
ВАР ответа = читатель.ReadToEnd();

Чем есть только черное окно в моей консоли.

Richard Deeming

Вы уверены, что весь XML-документ находится в одной строке?

Отлаживать свой код и проверить str переменная непосредственно перед xmlDoc.LoadXml(str); вызов; содержит ли он полный и действительный XML-документ?

Member 10261487

да. он содержит полный и действительный XML-документ.
Это показывает:

& lt;слой>
&ЛТ;auto_delta&ГТ;нуль

&ЛТ;рамка-кол&ГТ;5236&ЛТ;/Frame-номер&ГТ;
<nb_frames> 45001
&ЛТ;рамки-левый&ГТ;39765&ЛТ;/кадров-левое&ГТ;
&ЛТ;рама-возраст и gt;160&ЛТ;/рамка-возраст&ГТ;
& lt;производитель>
< type>ffmpeg
< filename> media\JTV. AVI
& lt;ширина> 720
& lt;высота & gt;576
&ЛТ;прогрессивный&ГТ;правда&ЛТ;/прогрессивные&ГТ;
& lt;fps> 25
& lt;loop & gt;false
&ЛТ;рамка-кол&ГТ;5237&ЛТ;/Frame-номер&ГТ;
< nb-frames & gt;45001
< файл-кадр-номер> 0
< file-nb-frames> 45001
< / производитель>
& lt;фон>
& lt;производитель>
< тип & gt;пустой-производитель
< / производитель>

& lt;индекс> 0


Разве это не справедливо ?

Richard Deeming

1) это не одна строка;
2) это не полный и действительный XML-документ;

Sergey Alexandrovich Kryukov

Конечно, но сам XML-файл действителен. :-)
Я попытался объяснить, что делать в решении 1. Ваши комментарии, конечно, засчитываются.
—СА

2 Ответов

Рейтинг:
6

Member 10261487

Я ее разгадал.

мой код:

XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(str);
XmlNodeList nodeList = xmlDoc.GetElementsByTagName("file-nb-frames");
            string file_nb_frames = string.Empty;
            foreach (XmlNode node in nodeList)
            {
                file_nb_frames = node.InnerText;
            }

            Console.WriteLine(file_nb_frames);


Сейчас это работает. Спасибо всем.


Рейтинг:
1

Sergey Alexandrovich Kryukov

Ричард Диминг прав — пожалуйста, посмотрите его комментарии к этому вопросу.

Да, ваш XML-файл действителен. Если бы вы его проанализировали, он бы прекрасно разбирался.

Но вы не анализируете этот файл с помощью своего кода. Вы делаете что-то совершенно бессмысленное. Вы звоните LoadXml только не с этим досье. Вы пытаетесь разобрать только ту строку, которая является строкой str рассчитывается от reply, удалив некоторые жестко закодированные строки. Это совсем не XML. Неудивительно, что XML-парсер не может разобрать какой-то текст, который не является XML.

Что же делать? Сначала разберите весь файл целиком (в вашем случае из потока, XmlDocument.Метод Загрузки (Поток) (System.Xml)), чем изменить то, что вы хотите.

Вы никогда не должны читать строки из потока или файла, чтобы разобрать XML, если только вы не хотите создать свой собственный парсер, который вряд ли может иметь какой-либо практический смысл.

—СА


Member 10261487

На самом деле в этой ситуации нет никакого xml-файла. Я получу только строковый поток, который выглядит как xml. Итак, как я могу получить свое целевое значение из этой строки?

Sergey Alexandrovich Kryukov

Я знаю, это учтено в моем ответе. Пожалуйста, прочтите его более внимательно. Это не имеет никакого значения, файл или поток. Я предоставил ссылку на метод загрузки с помощью stream.
—СА

Member 10261487

Но здесь вы не можете использовать метод Load, потому что я работаю со строкой. Вы можете использовать метод Load только в том случае, если у вас есть xml-файл. Но, когда вы будете использовать String и формат строки будет так же похож на XML, чем вы должны использовать метод LoadXML (). https://msdn.microsoft.com/en-us/library/system.xml.xmldocument.loadxml(v=против 110). aspx

Теперь у меня есть правильная строка. И получение нового исключения: ссылка на объект не задана.

мой код:
XmlDocument xmlDoc = новый XmlDocument();
xmlDoc. LoadXml(str);
string frame_path = " слой / производитель";
var nodes_frame = xmlDoc. SelectNodes(frame_path);

пробовать
{
foreach (XmlNode childrenNode_frame в nodes_frame)
{
Приставка.WriteLine ("Frames:" + childrenNode_frame.SelectSingleNode ("//file-nb-frames").Ценность.ToString () + "частота кадров:" + childrenNode_frame.SelectSingleNode ("//fps").Ценность.Метод toString());
}
}
поймать (исключение ошибаться)
{
Приставка.WriteLine(err. ToString());
}

Sergey Alexandrovich Kryukov

Я читаю первую строчку вашего комментария. Ответ: неправда.
—СА