Как предотвратить пропуск XmlReader до конца файла или как сбросить настройки чтения - PullRequest
2 голосов
/ 09 июля 2011

Вот часть XML-файла, который я читаю:

<?xml version="1.0"?>
<movie xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ThumbGen="1">
  <hasrighttoleftdirection>false</hasrighttoleftdirection>
  <title>A Nightmare on Elm Street</title>
  <originaltitle>A Nightmare on Elm Street</originaltitle>
  <year>1984</year>
  <plot>Years after being burned alive by a mob of angry parents, child murderer Freddy Krueger returns to haunt the dreams -- and reality -- of local teenagers. As the town's teens begin dropping like flies, Nancy and her boyfriend, Glen, devise a plan to lure the monster out of the realm of nightmares and into the real world.</plot>
  <tagline>A scream that wakes you up, might be your own...</tagline>
  <metascore>78</metascore>
  <trailer>http://www.youtube.com/watch?v=996</trailer>
  <rating>8.6</rating>
  <episodes />
  <episodesnames />
  <writers />
  <gueststars />
  <id>tt0087800</id>
  <releasedate>11.09.1984</releasedate>
  <actor>
    <name>Robert Englund</name>
    <name>Heather Langenkamp</name>
    <name>Johnny Depp</name>
    <name>Ronee Blakley</name>
    <name>John Saxon</name>
    <name>Amanda Wyss</name>
    <name>Jsu Garcia</name>
    <name>Charles Fleischer</name>
    <name>Joseph Whipp</name>
    <name>Lin Shaye</name>
    <name>Joe Unger</name>
    <name>Mimi Craven</name>
    <name>David Andrews</name>
  </actor>
  <genre>
    <name>Horror</name>
    <name>Comedy</name>
  </genre>
  <director>
    <name>Wes Craven</name>
  </director>
  <runtime>91</runtime>
  <certification>R</certification>
  <studio>
    <name>New Line Cinema</name>
  </studio>
  <country>
    <name>United States of America</name>
  </country>
  ...
  ...
  ...
</movie>

Проблема, с которой я сталкиваюсь, заключается в том, что, когда я проверяю MPAA, если он не существует, он запускается доконец файла, и я застреваю там.Не все фильмы будут иметь MPAA, и по какой-то причине XML не содержит пустой элемент в этом случае.

Мне нужно выяснить, как я могу проверить его, а не потерять позициюили как я могу сбросить положение считывателя обратно наверх.

Я пробовал reader.ResetState (), но я получаю ошибку «Root element is missing».

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

Да, я в беспорядке.

Я признаю, что я новичок в XML.Надеюсь, вы сможете понять, что происходит с кодом ниже.Я был бы очень признателен за предложения о лучших / альтернативных способах обработки этих файлов XML.У меня их около 2000, и они в среднем 360 строк (15 КБ), но некоторые из них 500 строк (50 КБ).

public static void ProcessMovies(string wPath, string cPath, string iPath)
{
    int lineID = 0;
    string strMovie = null;
    string strTitle = null;
    string strYear = null;
    string strPlot = null;
    string strRating = null;
    string strMPAA = null;
    string strCertification = null;
    string strGenre = null;

    // initiates streamwriter for output file
    FileInfo fi = new FileInfo(cPath + Path.DirectorySeparatorChar + "catalog.html");
    StreamWriter catalog = fi.AppendText();

    // pulls list of file and sorts them alphabetically
    // TODO: do "library sort" that ignores The, A at beginning of title
    string[] fns = Directory.GetFiles(wPath, "*.nfo");
    var sort = from fn in fns
               orderby new FileInfo(fn).Name ascending
               select fn;

    foreach (string n in sort)
    {
        if (lineID == 0)
            catalog.WriteLine("         <tr id=\"odd\">");
        else
            catalog.WriteLine("         <tr id=\"even\">");
        Console.WriteLine("Processing: " + n);

        XmlTextReader reader = new XmlTextReader(n);

            reader.ReadToFollowing("title");
            strTitle = reader.ReadElementContentAsString();

            reader.ReadToFollowing("year");
            strYear = reader.ReadElementContentAsString();

            reader.ReadToFollowing("plot");
            strPlot = reader.ReadElementContentAsString();

            reader.ReadToFollowing("rating");
            strRating = reader.ReadElementContentAsString();

                if (reader.ReadToFollowing("mpaa"))
                    strMPAA = reader.ReadElementContentAsString();
                else
                    strMPAA="UNKNOWN";

            // ugly code to try to read multiple embedded <name> elements within <genre>
            // NOTE: Possible only 1 genre
            reader.ResetState();
            reader.ReadToFollowing("genre");
            reader.Read();
            while ((reader.Name != "genre"))
            {
                reader.Read();
                if (reader.NodeType == XmlNodeType.Text)
                    strGenre += reader.Value + ", ";
            }
            strGenre = strGenre.Substring(0, strGenre.Length - 2);

            reader.ReadToFollowing("certification");
            strCertification = reader.ReadElementContentAsString();

            reader.Close();

        strMovie =  "               <td>\r\n" + "                   <img src=\"" + JPG_FILE_NAME + "\" width=\"75\" height=\"110\">\r\n" + "                </td>\r\n" + "              <td>\r\n" + "                   <div id=\"title\">" + strTitle + "</div>" + "                   <div id=\"mpaa\">" + strMPAA + "</div>" + "                 <div id=\"genre\">" + strGenre + "</div>" + "                   <div id=\"plot\">" + strPlot + "</div>" + "             </td>" + "          </tr>";
        catalog.WriteLine(strMovie);

    }
    catalog.Close();
}


******************** EDIT ********************

Хорошо, я отредактировал код, который обрабатывает XML, в соответствии с Хенкомпредложение:

var doc = XDocument.Load(n);  // takes care of all Open/Close issues
strTitle = doc.Root.Element("title") == null ? "" : doc.Root.Element("title").Value;
                strYear = doc.Root.Element("year") == null ? "" : doc.Root.Element("year").Value;
                strPlot = doc.Root.Element("plot") == null ? "" : doc.Root.Element("plot").Value;
                strRating = doc.Root.Element("rating") == null ? "" : doc.Root.Element("rating").Value;
                strMPAA = doc.Root.Element("mpaa") == null ? "" : doc.Root.Element("mpaa").Value;
                strCertification = doc.Root.Element("certification") == null ? "" : doc.Root.Element("certification").Value;

Отлично работает, большое спасибо !!!

Теперь, наконец, как можно получить Жанры из названия жанра, используя этот метод?Я не могу искать элемент name, так как он используется в различных элементах.Я не был уверен, смогу ли я работать с:

doc.Root.Element("genre").ElementsAfterSelf("name");

Не было ясно, что это возвращает, или как он будет обрабатывать несколько «имен».

1 Ответ

2 голосов
/ 09 июля 2011

Если ваши данные не >> 100 МБ, считайте их в XDocument или XmlDocument.

С XmlTextReader вы не можете искать дополнительные элементы. Вы можете извлекать и хранить каждый элемент только по мере его поступления, а затем «искать» свои элементы в своих собственных структурах данных.

Грубо говоря, используя Sytem.Xml.Linq

 var doc = XDocument.Load(fileName);  // takes care of all Open/Close issues
 string title = doc.Element("title").Value;
 string mpaa = doc.Element("title") == null ? "" : doc.Element("mpaa").Value;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...