使用XmlReader读取嵌套子树

本文关键字:嵌套 读取 XmlReader 使用 | 更新日期: 2023-09-27 18:12:44

我在将XML解析为数据库时遇到了一个问题。我的XML结构是这样的:

<atrists>
<artist>
<images>
<image/>
</images>
<id>
</id>
</artist>
</artists>

有很多艺术家标签。在艺术家中有很多标签。

我现在正在做什么:

while (reader.ReadToFollowing("artist"))
{
 XmlReader reader2 = reader.ReadSubtree();
while (reader2.Read())
{
 if (reader2.NodeType == XmlNodeType.Element)
  {
  if (reader2.Name == "images")
  {
 while (reader2.ReadToFollowing("image"))
  {
//here i am adding all images data to lists to query it later
  }
  }
if (reader2.Name == "id")
{
 id = reader2.ReadElementContentAsInt();
}
}

//这里我想做SQL查询,将添加许多图像和ID附加到每个。

}

这个id不能正常工作。它会跳过50%的ID,或者根本不会改变。但我能看到所有可能的图像。所以我觉得从一个节点到另一个节点有问题。什么好主意吗?

使用XmlReader读取嵌套子树

试试这个:

    async Task BigFileReader(System.IO.Stream stream)
    {
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.Async = true;
        bool bIdEncountered = false;
        using (XmlReader reader = XmlReader.Create(stream, settings))
        {
            while (await reader.ReadAsync())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        bIdEncountered = reader.LocalName.Equals("id");
                        break;
                    case XmlNodeType.Text:
                        var value = await reader.GetValueAsync();
                        if(bIdEncountered) Console.WriteLine("Run my SQL for {0}", value);
                        break;
                    case XmlNodeType.EndElement:
                        break;
                    default:
                        break;
                }
            }
        }
    }
示例2

也许这会给你一个更好的例子:

    async Task BigFileReader(System.IO.Stream stream)
    {
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.Async = true;
        bool bIdEncountered = false;
        bool bImageEncountered = false;
        List<string> images = new List<string>();
        int artistId = 0;
        using (XmlReader reader = XmlReader.Create(stream, settings))
        {
            while (await reader.ReadAsync())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        bIdEncountered = reader.LocalName.Equals("id");
                        bImageEncountered = reader.LocalName.Equals("image");
                        if(reader.LocalName.Equals("images")) images.Clear();
                        break;
                    case XmlNodeType.Text:
                        //var value = await reader.GetValueAsync();
                        if (bIdEncountered) artistId = Convert.ToInt32(await reader.GetValueAsync());
                        if (bImageEncountered) images.Add(await reader.GetValueAsync());
                        break;
                    case XmlNodeType.EndElement:
                        if (reader.LocalName.Equals("artist")) Console.WriteLine("Saving artist {0} with images {1}", artistId, String.Join(",", images));
                        break;
                    default:
                        break;
                }
            }
        }
    }

属性的示例

    async Task BigFileReader(System.IO.Stream stream)
    {
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.Async = true;
        bool bIdEncountered = false;
        List<ImageNode> images = new List<ImageNode>();
        int artistId = 0;
        using (XmlReader reader = XmlReader.Create(stream, settings))
        {
            while (await reader.ReadAsync())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        bIdEncountered = reader.LocalName.Equals("id");
                        //bImageEncountered = reader.LocalName.Equals("image");
                        if(reader.LocalName.Equals("images")) images.Clear();
                        if (reader.LocalName.Equals("image"))
                        {
                            images.Add( new ImageNode
                                    {
                                        Width = Convert.ToInt32(reader.GetAttribute("width")),
                                        Height = Convert.ToInt32(reader.GetAttribute("height")),
                                        Url = reader.GetAttribute("uri")
                                    });
                        }
                        break;
                    case XmlNodeType.Text:
                        if (bIdEncountered) artistId = Convert.ToInt32(await reader.GetValueAsync());
                        break;
                    case XmlNodeType.EndElement:
                        if (reader.LocalName.Equals("artist")) Console.WriteLine("Saving artist {0} with images {1}", artistId, String.Join(",", images));
                        break;
                    default:
                        break;
                }
            }
        }
    }

internal class ImageNode    
{
    public int Width { get; set; }
    public int Height { get; set; }
    public string Url { get; set; }
    public override string ToString() { return String.Format("{0}x{1}:{2}", Width, Height, Url); }
}
同步版本 (VS2010)
    static void BigFileReader(System.IO.Stream stream)
    {
        XmlReaderSettings settings = new XmlReaderSettings();
        bool bIdEncountered = false;
        List<ImageNode> images = new List<ImageNode>();
        int artistId = 0;
        using (XmlReader reader = XmlReader.Create(stream, settings))
        {
            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        bIdEncountered = reader.LocalName.Equals("id");
                        //bImageEncountered = reader.LocalName.Equals("image");
                        if (reader.LocalName.Equals("images")) images.Clear();
                        if (reader.LocalName.Equals("image"))
                        {
                            images.Add(new ImageNode
                            {
                                Width = Convert.ToInt32(reader.GetAttribute("width")),
                                Height = Convert.ToInt32(reader.GetAttribute("height")),
                                Url = reader.GetAttribute("uri")
                            });
                        }
                        break;
                    case XmlNodeType.Text:
                        if (bIdEncountered) artistId = Convert.ToInt32(reader.Value);
                        break;
                    case XmlNodeType.EndElement:
                        if (reader.LocalName.Equals("artist")) Console.WriteLine("Saving artist {0} with images {1}", artistId, String.Join(",", images));
                        break;
                    default:
                        break;
                }
            }
        }
    }