是否有解析一个父 XML 节点中包含的所有信息的最佳实践?
Is there a best practice for parsing all information contained within one parent XML node?
我正在编写一个 VB.NET 应用程序来解析一个很大的 XML 文件,它是一本日语词典。我对 XML 解析完全陌生,真的不知道自己在做什么。整个字典适合两个 XML 标签 <jmdict>
和 </jmdict>
。下一层是<entry>
,包含了100万个词条的所有信息,包括词的形式、读音、词义等。
典型的条目可能如下所示:
<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>
我有一个 class 对象,Entry
,它用于存储条目中包含的所有信息,如上面的条目。我知道所有标签的含义,我对从语义上解释数据没有问题,我只是不确定我需要什么工具来实际解析所有这些信息。
比如<ent_seq>
标签开头的内容应该怎么提取?用于从 XML 标签中提取信息的方法是否相同,即使它包含在父标签中,如在 [=20= 中包含的 <keb>
和 <ke_pri>
标签中一样] 标签?或者我应该使用不同的方法?
我知道这读起来像是家庭作业帮助 - 我并不是要有人提供完整的解决方案并构建解析器。我只是不知道从哪里开始以及使用什么工具。我非常感谢有关 方法 我需要开始解析 XML 文件的一些指导,然后一旦我知道我会自己构建解决方案'我在做。
-
编辑
所以我从 this website 中看到这段代码,它使用 XMLReader 一次通过一个节点:
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' is a class type and cannot be used as an expression
我不太确定如何处理这个错误 - 有什么想法吗?
您可以使用这些 类 快速反序列化您的 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
您的代码花费这么长时间的原因是
- 您正在将 xml 解析为字符串
- 您在解析行时将行插入到列表框中
您想在列表框中放入什么?如果你像我展示的那样反序列化,你可以从数据中绑定一个特定的列表,或者多个列表的查询结果。
我正在编写一个 VB.NET 应用程序来解析一个很大的 XML 文件,它是一本日语词典。我对 XML 解析完全陌生,真的不知道自己在做什么。整个字典适合两个 XML 标签 <jmdict>
和 </jmdict>
。下一层是<entry>
,包含了100万个词条的所有信息,包括词的形式、读音、词义等。
典型的条目可能如下所示:
<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>
我有一个 class 对象,Entry
,它用于存储条目中包含的所有信息,如上面的条目。我知道所有标签的含义,我对从语义上解释数据没有问题,我只是不确定我需要什么工具来实际解析所有这些信息。
比如<ent_seq>
标签开头的内容应该怎么提取?用于从 XML 标签中提取信息的方法是否相同,即使它包含在父标签中,如在 [=20= 中包含的 <keb>
和 <ke_pri>
标签中一样] 标签?或者我应该使用不同的方法?
我知道这读起来像是家庭作业帮助 - 我并不是要有人提供完整的解决方案并构建解析器。我只是不知道从哪里开始以及使用什么工具。我非常感谢有关 方法 我需要开始解析 XML 文件的一些指导,然后一旦我知道我会自己构建解决方案'我在做。
-
编辑
所以我从 this website 中看到这段代码,它使用 XMLReader 一次通过一个节点:
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' is a class type and cannot be used as an expression
我不太确定如何处理这个错误 - 有什么想法吗?
您可以使用这些 类 快速反序列化您的 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
您的代码花费这么长时间的原因是
- 您正在将 xml 解析为字符串
- 您在解析行时将行插入到列表框中
您想在列表框中放入什么?如果你像我展示的那样反序列化,你可以从数据中绑定一个特定的列表,或者多个列表的查询结果。