从 XML 读取数据 [重复]

Posted

技术标签:

【中文标题】从 XML 读取数据 [重复]【英文标题】:Reading data from XML [duplicate] 【发布时间】:2011-10-30 11:50:18 【问题描述】:

我打算将 XML 用于数据库目的。我唯一能做的就是读取整个 XML 文件。我希望能够只读取一些数据,但我不知道该怎么做。

这是一个简单的 XML

<Books>
 <Book>
  <Title>Animals</Title>
  <Author>J. Anderson</Author>
 </Book>
 <Book>
  <Title>Car</Title>
  <Author>L. Sawer</Author>
 </Book>
</Books> 

我对输出的应用感兴趣

Books:
Animals
Cars

Authors:
J. Anderson
L. Sawer

我只是想了解如何从 XML 而不是整个文件中读取特定数据。

[已解决] 我用过 Linq to XML

【问题讨论】:

文件是否太大而无法完整读取?您可以使用 XmlReader 来读取位,但是通过 LINQ to XML 读取批次然后只需 select 会更简单很多你想要的…… 文件不太大,大约 5-10 KB 【参考方案1】:

我认为您不能“合法地”仅加载 XML 文件的一部分,因为那样它就会出现格式错误(某处会缺少结束元素)。

使用 LINQ-to-XML,您可以执行 var doc = XDocument.Load("yourfilepath")。从那里只需查询您想要的数据,这样说:

var authors = doc.Root.Elements().Select( x => x.Element("Author") );

HTH。

编辑:

好的,为了让这个样本更好,试试这个(@JWL_ 的建议改进):

using System;
using System.Xml.Linq;

namespace ConsoleApplication1 
    class Program 
        static void Main( string[] args )  
            XDocument doc = XDocument.Load( "XMLFile1.xml" );
            var authors = doc.Descendants( "Author" );
            foreach ( var author in authors ) 
                Console.WriteLine( author.Value );
            
            Console.ReadLine();
        
    

您需要调整 XDocument.Load() 中的路径以指向您的 XML 文件,但其余的应该可以工作。就您不理解的部分提出问题。

【讨论】:

我认为 doc.Decendants("Author") 是更好的选择。 @JWL_ 可能。老实说,我只是输入了想到的第一件事。感谢您的输入! :) 我正在尝试使用此代码,但我很困惑下一步该做什么。当我使用 Console.WriteLine(authors);它显示了一些废话。我真的不明白它是如何工作的。你能把更完整的代码放在这里吗?谢谢 好吧,authors 将是 XElements 的 IEnumerable 集合,所以是的,Console.WriteLine() 只会为您提供底层 object 的默认 .ToString()。跨度> 我使用了 var authors = doc.Root.Elements().Select(x => x.Element("Author")); foreach (var author in authors) Console.WriteLine(author); 【参考方案2】:

根据@Jon Skeet 的评论,只有当您的文件非常大时,您才应该使用 XmlReader。以下是如何使用它。 假设你有一个 Book 类

public class Book 
    public string Title get; set;
    public string Author get; set;

您可以使用较小的内存占用逐行读取 XML 文件,如下所示:

public static class XmlHelper 
    public static IEnumerable<Book> StreamBooks(string uri) 
        using (XmlReader reader = XmlReader.Create(uri)) 
            string title = null;
            string author = null;

            reader.MoveToContent();
            while (reader.Read()) 
                if (reader.NodeType == XmlNodeType.Element
                    && reader.Name == "Book") 
                    while (reader.Read()) 
                        if (reader.NodeType == XmlNodeType.Element &&
                            reader.Name == "Title") 
                            title = reader.ReadString();
                            break;
                        
                    
                    while (reader.Read()) 
                        if (reader.NodeType == XmlNodeType.Element &&
                            reader.Name == "Author") 
                            author =reader.ReadString();
                            break;
                        
                    
                    yield return new Book() Title = title, Author = author;
                
                   
        
    

使用示例:

string uri = @"c:\test.xml"; // your big XML file

foreach (var book in XmlHelper.StreamBooks(uri)) 
    Console.WriteLine("Title, Author: 0, 1", book.Title, book.Author);  

【讨论】:

非常感谢,这正是我认为可以做到的。我的数据库不大,不超过 50 条记录 好吧,那么我不会真正使用这种方法。如您所见,要完成 Linq.Xml 将在 2 或 3 行代码中执行的操作,需要大量代码。例如,看看@Tieson T. 的答案。 是的,这是一个好方法,但 Linq 更适合我的目的【参考方案3】:

或者,您可以使用 XPathNavigator:

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XPathNavigator navigator = doc.CreateNavigator();

string books = GetStringValues("Books: ", navigator, "//Book/Title");
string authors = GetStringValues("Authors: ", navigator, "//Book/Author");

..

/// <summary>
/// Gets the string values.
/// </summary>
/// <param name="description">The description.</param>
/// <param name="navigator">The navigator.</param>
/// <param name="xpath">The xpath.</param>
/// <returns></returns>
private static string GetStringValues(string description,
                                      XPathNavigator navigator, string xpath) 
    StringBuilder sb = new StringBuilder();
    sb.Append(description);
    XPathNodeIterator bookNodesIterator = navigator.Select(xpath);
    while (bookNodesIterator.MoveNext())
       sb.Append(string.Format("0 ", bookNodesIterator.Current.Value));
    return sb.ToString();

【讨论】:

你能看到我的question 之一关于 xml 响应吗?【参考方案4】:

尝试使用 XMLDocument 类的 GetElementsByTagName 方法读取特定数据或使用 LoadXml 方法将所有数据读取到 xml 文档中。

【讨论】:

以上是关于从 XML 读取数据 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用 scala 从 HDFS 读取输入 xml 数据

如何从 xml 解析器中读取数据

从多个表中读取数据的问题[重复]

如何从firebase读取子数据[重复]

使用 Linq 从在线 XML 文件中读取数据

Flink读取HDFS中的xml(一)——读取XML的几种方式