Member 12111727 Ответов: 2

Читать строки между <text> & lt;/text> и загружать их в поле со списком?


Im making an RSS Feed reader, in which I categorize feeds, and per category has a list of different RSS Feeds that the user will be able to customize. I want categorize all the feeds inside a single text file, for easy editing, and get every line between <category1></category1>injected into a combo box. Example:

<category1>
feed1
feed2
feed3
</ccategory1>
<category2>
feed4
feed5
</category2>

With the combobox for Category1 only recieiving the text:
feed1
feed2
feed3

While the same combobox is filled with Category 2 upon selection, looking like this:
feed4
feed5


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

Google, никогда не был хорош с StreamReaders/Writers

MadMyche

Было бы полезно посмотреть код... это намного облегчает понимание того, что с ним может быть не так

Richard MacCutchan

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

Member 12111727

У меня нет проблем с моим XML-стримером, это потоковая передача текстовых файлов. Я не знаю, как найти фрагмент текста, в данном случае: фрагмент между <category1> и <_/category1>

Было бы проще писать и читать в xml, а не в текстовый файл?

Richard MacCutchan

Возможно, проще записать его в XML, но все зависит от того, что вы пытаетесь сделать. Чтение простого текстового файла и проверка на наличие ключевых слов в форме, показанной выше, - это довольно простой процесс.

Member 12111727

Это все, что я хочу сделать. В основном у меня есть поле со списком и DataviewGrid. Мой класс RSSParser заботится о переводе известных RSS-каналов и перечислении элементов в DataViewGrid, все, что я хочу сделать, это иметь возможность выбрать с помощью поля со списком, какой канал я хочу заполнить GridView.

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

2 Ответов

Рейтинг:
2

phil.o

На самом деле вам не нужно иметь дело с stream reader:

Public Shared Function GetFeeds(ByVal doc As XmlDocument, ByVal category As String) As String()

   If (doc Is Nothing) Then 
      Throw New ArgumentNullException(NameOf(doc))
   End If

   Dim node As XmlElement = CType(doc.DocumentElement.SelectSingleNode("//" + category), XmlElement)

   If (node IsNot Nothing) Then
      Return node.InnerText.Split(New String() { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
   Else
      Return New String() { }
   End If

End Function

'' Usage
Dim doc As XmlDocument = XmlDocument.Load("path\to\your\xml\file")
Dim feeds1 As String() = GetFeeds(doc, "category1")
Dim feeds2 As String() = GetFeeds(doc, "category2")

comboBox1.Items.AddRange(feeds1)
combobox2.Items.AddRange(feeds2)

Там могут быть некоторые ошибки, так как я использовал c# для vb.net конвертер (я не пишу vb.net кода больше нет), но это краткий способ получить элементы combobox из вашего xml-файла.


Member 12111727

Единственная проблема, с которой я сталкиваюсь, заключается в том, что XmlDocument не имеет a .Функция нагрузки

phil.o

Возможно, вам придется добавить ссылку на System.Xml.dll-да.
То Load метод действительно существует:
XmlDocument.метод Load

Member 12111727

Хорошо, он исправил это, но теперь он просто не работает, никаких ошибок. Мне пришлось немного одифицировать код, потому что элемент документа не работал, поэтому я переключил его на элементы

Public Function GetFeeds(ByVal FeedsDoc As XDocument, ByVal category As String) As String()

If (FeedsDoc Is Nothing) Then
Throw New ArgumentNullException(NameOf(FeedsDoc))
End If

Dim node As XmlElement = CType(FeedsDoc.Elements("/category/" + category + "/link"), XmlElement)

If (node IsNot Nothing) Then
Return node.InnerText.Split(New String() {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
Else
Return New String() {}
End If

End Function

Member 12111727

Мой RSS-канал XML



<category>
<earthquake>
<link>https://www.volcanodiscovery.com/volcanonews.rss</link>
</earthquake>
<volcano>
<link>https://www.volcanodiscovery.com/volcanonews.rss</link>
</volcano>
<hurricane>
<link>https://www.volcanodiscovery.com/volcanonews.rss</link>
</hurricane>
<tsunami>
<link>https://www.volcanodiscovery.com/volcanonews.rss</link>
</tsunami>
<space>
<link>https://www.volcanodiscovery.com/volcanonews.rss</link>
</space>
<disease>
<link>https://www.volcanodiscovery.com/volcanonews.rss</link>
</disease>
<custom>
<link>https://www.volcanodiscovery.com/volcanonews.rss</link>
</custom>
</category>

phil.o

Я написал: XmlDocument- ты же сам писал XDocument Это различные объекты, обычаи которых также различны.

Member 12111727

Итак, я вернулся к вашему оригиналу. Ошибка для XmlDocument.Нагрузка("myfile.xml")-это "ссылка на не разделяемый член требует Ссылки на объект"

phil.o

Мой плохой; попробуй

Dim doc As New XmlDocument()
doc.Load("path\to\your\xml\file")
вместо.

Member 12111727

Нет. Опять же, никаких ошибок, но это мешает моему DataGridView заполняться

Member 12111727

Поэтому я снял всю эту штуку и заменил ее вот этим:

Public Function FillFeedList(combo As ComboBox, category As String)
        'Connect to Internal Feed Database
        Dim path As String = "RSSFeeds.xml"
        Dim feedDoc As New XmlDocument()
        feedDoc.Load(path)

        Dim selectedCategory As XmlNodeList = feedDoc.SelectNodes("category/" + category)
        Dim i As Integer = 0
        For Each node In selectedCategory.Item(i)
            Dim feedLink As XmlNode = selectedCategory.Item(i).SelectSingleNode("link")
            If feedLink IsNot Nothing Then
                'combo.Items.Add(feedLink.InnerText)
                combo.DataSource = (From element In feedLink Select element.Value).ToList()
            Else
                combo.Text = Nothing
            End If
        Next

        i += 1
        Return Nothing


    End Function


единственная проблема в том, что он по-прежнему загружает только один канал, первый.
Я скопировал кучу ссылок в ленту эквалайзера вот так:
<?xml version="1.0"?>
<category>
  <earthquake>
      <link>https://www.volcanodiscovery.com/volcanonews.rss</link>
      <link>https://www.volcanodiscovery.com/volcanonews.rss</link>
      <link>https://www.volcanodiscovery.com/volcanonews.rss</link>
      <link>https://www.volcanodiscovery.com/volcanonews.rss</link>
  </earthquake>
  <volcano>
      <link>https://www.volcanodiscovery.com/volcanonews.rss</link>
  </volcano>
  <hurricane>
      <link>https://www.volcanodiscovery.com/volcanonews.rss</link>
  </hurricane>
  <tsunami>
      <link>https://www.volcanodiscovery.com/volcanonews.rss</link>
  </tsunami>
  <space>
      <link>https://www.volcanodiscovery.com/volcanonews.rss</link>
  </space>
  <disease>
      <link>https://www.volcanodiscovery.com/volcanonews.rss</link>
  </disease>
  <custom>
      <link>https://www.volcanodiscovery.com/volcanonews.rss</link>
  </custom>
</category>

phil.o

Он выбирает только первый, потому что это то, что вы просите с вашим i переменная, которая инициализируется нулем (первый элемент) и увеличивается вне цикла: ваш цикл никогда не увидит другого значения для i чем ноль. Если вы хотите получить доступ на основе индекса, то не используйте ForEach петля, но равнина For петля вместо этого:

Dim selectedCategory As XmlNodeList = feedDoc.SelectNodes("category/" + category)
Dim elements As New List(Of String)
For i As Integer = 0 To selectedCategory.Count - 1
   Dim feedLink As XmlNode = selectedCategory.ItemOf(i)
   If feedLink IsNot Nothing Then
      elements.Add(feedLink.InnerText)
   End If
Next
combo.DataSource = elements

Member 12111727

Оооочень близко. Спасибо, но вместо того, чтобы размещать отдельные элементы, которые вы можете выбрать в выпадающем списке, он шлепает все элементы в 1

phil.o

Тогда может быть попробуем

combo.Items.AddRange(elements.ToArray())
вместо.

Member 12111727

Он говорит: "значение типа List(строки) не может быть преобразовано в объект()

phil.o

Исправленный. Вам нужно будет импортировать систему.Пространство имен Linq для ToArray() метод.

Member 12111727

Я уже пробовал это, никаких костей.

phil.o

Странно, потому что elements.ToArray() вернется а String() (строковый массив), который по своей сути является Object() (массив объектов).

Member 12111727

Я имею в виду, что он исправил ошибку, но она все еще отображается как один элемент в коробке cmombo

phil.o

Затем вы должны начать использовать отладчик и следить за содержимым файла. elements список. Вам нужна помощь в том, как провести сеанс отладки?

Member 12111727

Да, лол.

phil.o

Вот несколько ссылок, которые помогут вам начать отладку:
Учебник: научитесь отлаживать код Visual Basic с помощью Visual Studio
Точки останова и отладка
Знание того, как отлаживать, является важным навыком; это позволяет исследовать ваш код, чтобы понять, почему он не дает ожидаемых результатов.

Рейтинг:
12

Member 12111727

я понял. Оказывается проблема заключалась в том как я вызывал и использовал свои узлы и xmlDocument

Public Function FillFeedList(combo As ComboBox, category As String)
        'Connect to Internal Feed Database
        Dim path As String = "RSSFeeds.xml"
        Dim feedDoc As New XmlDocument()
        feedDoc.Load(path)

        Dim selectedCategory As XmlNode = feedDoc.SelectSingleNode("category/" + category)
        Dim elements As New List(Of String)
        For i As Integer = 0 To selectedCategory.ChildNodes.Count
            Dim feedLink As XmlNode = selectedCategory.ChildNodes.Item(i)
            If feedLink IsNot Nothing Then
                elements.Add(feedLink.InnerText)
            End If
        Next
        combo.Items.AddRange(elements.ToArray())
        Return Nothing


    End Function