Я пытаюсь разобрать большой словарь с английского на английский sh, написанный на XML. Типичная запись выглядит так:
<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>
Я написал десериализатор на основе кода, предоставленного djv в этом ответе , и он действительно десериализует весь словарь в серию Объекты класса. Вот код, который я получил до сих пор:
ReadOnly jmdictpath As String = "JMdict"
<XmlRoot>
Public Class JMdict
<XmlElement("entry")>
Public Property entrylist As List(Of entry)
End Class
<Serializable()>
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 senselist As List(Of sense)
End Class
<Serializable()>
Public Class k_ele
Public Property keb As String
Public Property ke_pri As List(Of String)
Public Property ke_inf As List(Of String)
End Class
<Serializable()>
Public Class r_ele
Public Property reb As String
Public Property re_pri As List(Of String)
Public Property ke_inf As List(Of String)
End Class
<Serializable()>
Public Class sense
<XmlElement("pos")>
Public Property pos As List(Of string)
<XmlElement("gloss")>
Public Property gloss As List(Of gloss)
End Class
<Serializable()>
Public Class gloss
<XmlAttribute("xml:lang")>
Public Property lang As String
<XmlAttribute("g_type")>
Public Property g_type As String
<XmlText>
Public Property Text As String
Public Overrides Function ToString() As String
Return Text
End Function
End Class
Dim dict As JMdict
Sub Deserialise()
Dim serialiser As New XmlSerializer(GetType(JMdict))
Using sr As New StreamReader(jmdictpath)
dict = CType(serialiser.Deserialize(sr), JMdict)
End Using
End Sub
Однако, когда я запускаю код, я получаю следующую ошибку:
System.InvalidOperationException: 'Существует ошибка в документе XML (415, 7). '
XmlException: непредвиденный тип узла EntityReference. Метод ReadElementString можно вызывать только для элементов с простым или пустым содержимым. Строка 415, позиция 7.
Я проверил XML, а строка 415 - это строка:
<pos>&unc;</pos>
Таким образом, десериализатор испытывает проблемы с чтением <pos>
тег. Поэтому я попробовал несколько вещей.
Сначала я попытался удалить тег <XMLElement>
для pos
в классе sense
. Это означало, что ошибки не было, но десериализатор просто не считывал данные для pos
ни для одной из записей.
Во-вторых, я проверил StackOverflow и обнаружил, что это связано Вопрос, где у ОП была такая же проблема . Принятый ответ на этот вопрос предложил разбить данные на следующие классы , поэтому я тоже попробовал это и создал новый класс pos
:
<Serializable()>
Public Class sense
<XmlElement("pos")>
Public Property pos As List(Of pos)
<XmlElement("gloss")>
Public Property gloss As List(Of gloss)
End Class
<Serializable()>
Public Class pos
<XmlText>
Public Property Text As String
Public Overrides Function ToString() As String
Return Text
End Function
End Class
И еще раз, пока этот не вызвал ошибок, элемент pos
был пустым в каждой записи. Каждый тег pos
содержит только одно значение - хотя может быть более одного тега pos
на тег sense
- поэтому я не думал, что ему нужен собственный объект класса. В любом случае, этот ответ не решил мою проблему, поэтому я и задаю этот вопрос.
Я совершенно новичок в десериализации XML и не совсем понимаю, что я делаю в Глубина - я пытаюсь понять механику этого на основе этот полезный ответ , но я, очевидно, здесь что-то не так. Любой совет будет оценен.