【问题标题】:XmlReader loop through nodeXmlReader 循环通过节点
【发布时间】:2013-04-12 15:18:32
【问题描述】:

大家好,我有以下代码:

    Using reader As XmlReader = XmlReader.Create(New StringReader(xmlString))
        reader.ReadToFollowing("GridChannel")
        Dim Channel As String = reader.GetAttribute("Channel")
        Dim DisplayName As String = reader.GetAttribute("DisplayName")

        reader.ReadToFollowing("Airings")
        reader.ReadToFollowing("GridAiring")

        Dim Title As String = reader.GetAttribute("Title")
        Dim EpisodeTitle As String = reader.GetAttribute("EpisodeTitle")
        Dim AiringTDurationime As String = reader.GetAttribute("AiringTDurationime")
        Dim isHD As Boolean = Convert.ToBoolean(reader.GetAttribute("isHD"))
        Dim TVRating As String = reader.GetAttribute("TVRating")
    End Using

上面的代码工作得很好,但我在循环 Airings 部分时遇到问题。

该部分的 XML 如下所示:

    <Airings>
        <GridAiring ProgramId="35951" SeriesId="3490" Title="Matlock" EpisodeTitle="Santa Claus" AiringTime="2013-04-12T14:00:00Z" Duration="60" Color="Color" AiringType="Unknown" CC="true" LetterBox="false" Stereo="false" HD="false" SAP="false" TVRating="TV-PG" Dolby="false" DSS="false" HDLevel="HD Level Unknown" DVS="false" Category="Other" Subcategory="drama" Sports="false"/>
        <GridAiring ProgramId="828869" SeriesId="1409" Title="In the Heat of the Night" EpisodeTitle="Hatton's Turn" AiringTime="2013-04-12T15:00:00Z" Duration="60" Color="Color" AiringType="Unknown" CC="true" LetterBox="false" Stereo="false" HD="false" SAP="false" TVRating="TV-PG@V" Dolby="false" DSS="false" HDLevel="HD Level Unknown" DVS="false" Category="Other" Subcategory="crime drama" Sports="false"/>
        <GridAiring ProgramId="978338" SeriesId="1409" Title="In the Heat of the Night" EpisodeTitle="Hatton's Turn" AiringTime="2013-04-12T16:00:00Z" Duration="60" Color="Color" AiringType="Unknown" CC="true" LetterBox="false" Stereo="false" HD="false" SAP="false" TVRating="TV-PG@V" Dolby="false" DSS="false" HDLevel="HD Level Unknown" DVS="false" Category="Other" Subcategory="crime drama" Sports="false"/>
        <GridAiring ProgramId="4210626" Title="WGN Midday News" AiringTime="2013-04-12T17:00:00Z" Duration="60" Color="Color" AiringType="New" CC="true" LetterBox="false" Stereo="true" HD="false" SAP="false" TVRating="None" Dolby="false" DSS="false" HDLevel="HD Level Unknown" DVS="false" Category="News" Subcategory="newscast" Sports="false"/>
        <GridAiring ProgramId="878716" SeriesId="1028666" Title="Walker, Texas Ranger" EpisodeTitle="El Coyote, Part 2" AiringTime="2013-04-12T18:00:00Z" Duration="60" Color="Color" AiringType="Unknown" CC="true" LetterBox="false" Stereo="true" HD="false" SAP="false" TVRating="TV-14@V" Dolby="false" DSS="false" HDLevel="HD Level Unknown" DVS="false" Category="Other" Subcategory="crime drama" Sports="false"/>
    </Airings>

【问题讨论】:

  • 同意。您需要使用XmlReader吗?
  • @StevenDoggart 不,我没有,但这是我发现的最好的例子。随意告诉我一个更好的方法吗?
  • 如果您需要加载 XML 文档中的所有数据,我建议使用 XmlSerializer 类将文档反序列化为与文档结构匹配的对象。如果您只需要加载文档的某些部分,那么我建议您使用带有 XPath 的 XmlDocument 或带有 LINQ 的 XDocument
  • @StevenDoggart 在这里更新了我的 OP。

标签: xml vb.net parsing xml-parsing xmlreader


【解决方案1】:

可以循环执行此操作:

While reader.ReadToFollowing("GridAiring")
    Dim Title As String = reader.GetAttribute("Title")
    Dim EpisodeTitle As String = reader.GetAttribute("EpisodeTitle")
    Dim AiringTDurationime As String = reader.GetAttribute("AiringTDurationime")
    Dim isHD As Boolean = Convert.ToBoolean(reader.GetAttribute("isHD"))
    Dim TVRating As String = reader.GetAttribute("TVRating")
End While

【讨论】:

    【解决方案2】:

    不进入XML序列化,为什么不使用XmlReader.GetAttribute

    然后您应该能够将您的代码缩减为:

    Dim ServiceId As String = reader.GetAttribute("ServiceId")
    

    等等,这样更易​​读,更容易维护。

    编辑: 循环通过 XML,我更喜欢这种方式:

    Dim Airings As XDocument = XDocument.Parse(xmlString)
    For Each GridAiring As XElement In Airings.Root.Elements
      Dim ProgramId As String = GridAiring.Attribute("ProgramId").Value
      'read other properties here
    Next
    

    【讨论】:

    • 不过,这并不是一个真正的答案,是吗? :)
    • 因为它没有回答他的实际问题,即如何阅读Airings 元素。
    • @StevenDoggart:查看我的更新。现在算作答案吗?
    【解决方案3】:

    使用 LINQ 可以获得更好的性能,而不是循环。这是一个将 ProgramId、SeriesId 和 Title 拉入可枚举的示例。

    Dim document As XDocument = XDocument.Load("c:\tmp\test.xml")
    Dim airings = From i In document.Descendants("Airings")
                  Select New With
                         {Key .ProgramId = i.Attribute("ProgramId").Value,
                          Key .SeriesId = i.Attribute("SeriesId").Value,
                          Key .Title = i.Attribute("Title").Value}
    

    然后您可以遍历枚举。一个在控制台中打印结果的小例子

    For Each a In airings
        Console.WriteLine(String.Format("{0},{1},{2}", a.ProgramId, a.SeriesId, a.Title))
        Console.Read()
    Next
    

    每个项目的想法当然是您可以调用.ProgramId.SeriesId 等来获取价值

    如果您想添加检查以确保 Airing 没有缺少属性并防止可能的异常,您可以在 select 中添加检查以确保它存在,如下所示。

    Dim document As XDocument = XDocument.Load("c:\tmp\test.xml")
    Dim airings = From i In document.Descendants("Airings")
                  Where i.Attribute("ProgramId") IsNot Nothing _
                  And i.Attribute("SeriesId") IsNot Nothing _
                  And i.Attribute("Title") IsNot Nothing
                  Select New With
                         {Key .ProgramId = i.Attribute("ProgramId").Value,
                          Key .SeriesId = i.Attribute("SeriesId").Value,
                          Key .Title = i.Attribute("Title").Value}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-01
      • 2010-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多