Есть ли лучшая практика для анализа всей информации, содержащейся в одном родительском узле XML? - PullRequest
1 голос
/ 13 февраля 2020

Я пишу приложение VB. NET для анализа большого файла XML, который является японским словарем. Я совершенно новичок в разборе XML и не знаю, что я делаю. Весь словарь помещается между двумя XML тегами <jmdict> и </jmdict>. Следующий уровень - <entry>, который содержит всю информацию для 1 миллиона записей, включая форму, произношение, значение слова и т. Д.

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

<entry>
<ent_seq>1486440</ent_seq>
<k_ele>
<keb>美術</keb>
<ke_pri>ichi1</ke_pri>
<ke_pri>news1</ke_pri>
<ke_pri>nf02</ke_pri>
</k_ele>
<r_ele>
<reb>びじゅつ</reb>
<re_pri>ichi1</re_pri>
<re_pri>news1</re_pri>
<re_pri>nf02</re_pri>
</r_ele>
<sense>
<pos>&n;</pos>
<pos>&adj-no;</pos>
<gloss>art</gloss>
<gloss>fine arts</gloss>
</sense>
<sense>
<gloss xml:lang="dut">kunst</gloss>
<gloss xml:lang="dut">schone kunsten</gloss>
</sense>
<sense>
<gloss xml:lang="fre">art</gloss>
<gloss xml:lang="fre">beaux-arts</gloss>
</sense>
<sense>
<gloss xml:lang="ger">Kunst</gloss>
<gloss xml:lang="ger">die schönen Künste</gloss>
<gloss xml:lang="ger">bildende Kunst</gloss>
</sense>
<sense>
<gloss xml:lang="ger">Produktionsdesign</gloss>
<gloss xml:lang="ger">Szenographie</gloss>
</sense>
<sense>
<gloss xml:lang="hun">művészet</gloss>
<gloss xml:lang="hun">művészeti</gloss>
<gloss xml:lang="hun">művészi</gloss>
<gloss xml:lang="hun">rajzóra</gloss>
<gloss xml:lang="hun">szépművészet</gloss>
</sense>
<sense>
<gloss xml:lang="rus">изящные искусства; искусство</gloss>
<gloss xml:lang="rus">{~{的}} художественный, артистический</gloss>
</sense>
<sense>
<gloss xml:lang="slv">umetnost</gloss>
<gloss xml:lang="slv">likovna umetnost</gloss>
</sense>
<sense>
<gloss xml:lang="spa">bellas artes</gloss>
</sense>
</entry>

У меня есть объект класса Entry, который используется для хранения всей информации, содержащейся в записи, подобной приведенной выше. Я знаю, что означают все теги, у меня нет проблем с семантической интерпретацией данных, я просто не уверен, какие инструменты мне нужны для фактического анализа всей этой информации.

Например, как следует Извлечь содержимое тега <ent_seq> в начале? И является ли метод, используемый для извлечения информации из тега XML, таким же, даже если он содержится в родительском теге, как в тегах <keb> и <ke_pri>, которые содержатся в тегах <k_ele>? Или я должен использовать другой метод?

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

-

Редактировать

Итак, я столкнулся с этим кодом с этого веб-сайта , который использует XMLReader для go через один узел за один раз:

Dim readXML As XmlReader = XmlReader.Create(New StringReader(xmlNode))
While readXML.Read()
    Select Case readXML.NodeType
        Case XmlNodeType.Element
            ListBox1.Items.Add("<" + readXML.Name & ">")
            Exit Select
        Case XmlNodeType.Text
            ListBox1.Items.Add(readXML.Value)
            Exit Select
        Case XmlNodeType.EndElement
            ListBox1.Items.Add("")
            Exit Select
    End Select
End While

Но я получаю сообщение об ошибке в первой строке

'XmlNode' является типом класса и не может использоваться в качестве выражения

Я не совсем уверен, что делать с этой ошибкой - есть идеи?

1 Ответ

2 голосов
/ 13 февраля 2020

Вы можете использовать эти классы для быстрой десериализации вашего xml быстрого

Imports System.IO
Imports System.Xml.Serialization
<XmlRoot>
Public Class jmdict
    <XmlElement("entry")>
    Public Property entries As List(Of entry)
End Class
Public Class entry
    Public Property ent_seq As Integer
    Public Property k_ele As k_ele
    Public Property r_ele As r_ele
    <XmlElement("sense")>
    Public Property senses As List(Of sense)
End Class
Public Class sense
    <XmlElement("pos")>
    Public Property posses As List(Of String)
    <XmlElement("gloss")>
    Public Property glosses As List(Of gloss)
End Class
Public Class k_ele
    Public Property keb As String
    <XmlElement("ke_pri")>
    Public Property ke_pris As List(Of String)
End Class
Public Class r_ele
    Public Property reb As String
    <XmlElement("re_pri")>
    Public Property re_pris As List(Of String)
End Class
Public Class gloss
    <XmlAttribute("xml:lang")>
    Public Property lang As String
    <XmlText>
    Public Property Text As String
    Public Overrides Function ToString() As String
        Return Text
    End Function
End Class

Код для десериализации:

Dim serializer As New XmlSerializer(GetType(jmdict))
Dim d As jmdict
Using sr As New StreamReader("filename.xml")
    d = CType(serializer.Deserialize(sr), jmdict)
End Using

Теперь вы можете перебирать каждую запись, и чувства записей и глоссы чувств

For Each e In d.entries
    Console.WriteLine($"seq: {e.ent_seq}")
    For Each s In e.senses
        For Each g In s.glosses
            Console.WriteLine($"Text: {g.Text}, Lang: {g.lang}")
        Next
    Next
Next

Причины, по которым ваш код занимает так много времени:

  1. Вы анализируете xml как строку
  2. Вы вставляете строки в ListBox при их разборе

Что вы хотите поместить в ListBox? Если вы десериализовали, как я показываю, вы можете связать данные с указанным списком c из данных или запрошенным результатом нескольких списков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...