一个如何解析XML文件?[关闭]


492

有没有一种简单的方法来解析C#中的XML文件?如果是这样,该怎么办?


您可以使用以下实现:stackoverflow.com/a/34813985/5784646
Eulogy,2016年

好的,我重新打开了。重复项是XML Reader解决方案,其中涉及解析XML文件。该posssible副本中可以看到问题的编辑历史PS @GeorgeStocker
杰里米·汤普森

1
@JeremyThompson之所以重复的原因之一是另一个问题的答案要好得多。最简单的“仅链接”答案是无用的。
乔治·斯托克

1
@GeorgeStocker的问题足够不同,可以共存,并且都有很好的答案,而且被接受的问题都使用不同的技术。这就是为什么我投票决定让我们保持开放状态,我知道这个被接受的链接只是链接,但是它是MSDN,是在那之前写的,这是不可接受的,希望重新开放的副作用让Jon振作起来,阅读他的个人资料。反正加油。
杰里米·汤普森

Answers:



314

非常简单 我知道这些是标准方法,但是您可以创建自己的库来更好地处理。

这里有些例子:

XmlDocument xmlDoc= new XmlDocument(); // Create an XML document object
xmlDoc.Load("yourXMLFile.xml"); // Load the XML document from the specified file

// Get elements
XmlNodeList girlAddress = xmlDoc.GetElementsByTagName("gAddress");
XmlNodeList girlAge = xmlDoc.GetElementsByTagName("gAge"); 
XmlNodeList girlCellPhoneNumber = xmlDoc.GetElementsByTagName("gPhone");

// Display the results
Console.WriteLine("Address: " + girlAddress[0].InnerText);
Console.WriteLine("Age: " + girlAge[0].InnerText);
Console.WriteLine("Phone Number: " + girlCellPhoneNumber[0].InnerText);

另外,还有其他一些方法可以使用。例如,这里。而且我认为没有最佳方法可以做到这一点。您总是需要自己选择,最适合您的选择。


47
+1表示XmlDocument,在某些情况下,它比序列化接口更方便。如果您只需要一个特定元素,则可以使用索引器xmlDoc [“ Root”]访问子元素,并且可以将这些元素链接在一起:xmlDoc [“ Root”] [“ Folder”] [“ Item”]来挖掘子元素。层次结构(尽管确认这些元素确实存在是明智的)
Jason Williams 2010年

1
InnerText这里获取该节点的值,并与子节点的所有值连接在一起-对吗?似乎很奇怪。
Don Cheadle

17
一个有女性朋友名单的程序员?雪茄!
E. van Putten

1
@ E.vanPutten不在这个时代。这不是书呆子的复仇
user405205​​4

@DonCheadle如果你不希望在那里子节点,那么InnerText它将只返回节点值-这是我(也许其他人阅读这个问题)我解析XML首先找到。
F1Krazy

48

使用良好的XSD架构通过xsd.exe创建一组类,并使用XmlSerializerXML从XML中创建对象树,反之亦然。如果您对模型的限制很少,您甚至可以尝试使用Xml * Attributes在模型类和XML之间创建直接映射。

在MSDN上有一篇有关XML序列化的介绍性文章

性能提示:构建对象XmlSerializer是昂贵的。XmlSerializer如果您打算解析/写入多个XML文件,请保留对您实例的引用。



5
很好的例子是Microsoft提供的该示例中间的“购买订单示例”。msdn.microsoft.com/zh-CN/library/58a18dwa.aspx。您避免创建架构-您的c#类是架构,并带有C#属性。
Mark Lakata

25

如果要处理大量数据(许多兆字节),那么您想使用它XmlReader来对XML进行流解析。

别的(XPathNavigatorXElementXmlDocument甚至XmlSerializer如果你保持完整的生成对象图)将导致高内存使用情况,也是一个非常缓慢的加载时间。

当然,如果仍然需要内存中的所有数据,那么您可能没有太多选择。



10

最近,我被要求处理涉及XML文档解析的应用程序,并且我同意Jon Galloway的观点,我认为基于LINQ to XML的方法是最好的。但是,我确实需要挖掘一些信息以找到可用的示例,因此,事不宜迟,这里有一些示例!

欢迎任何注释,因为此代码有效,但可能并不完美,我想了解更多有关为此项目解析XML的信息!

public void ParseXML(string filePath)  
{  
    // create document instance using XML file path
    XDocument doc = XDocument.Load(filePath);

    // get the namespace to that within of the XML (xmlns="...")
    XElement root = doc.Root;
    XNamespace ns = root.GetDefaultNamespace();

    // obtain a list of elements with specific tag
    IEnumerable<XElement> elements = from c in doc.Descendants(ns + "exampleTagName") select c;

    // obtain a single element with specific tag (first instance), useful if only expecting one instance of the tag in the target doc
    XElement element = (from c in doc.Descendants(ns + "exampleTagName" select c).First();

    // obtain an element from within an element, same as from doc
    XElement embeddedElement = (from c in element.Descendants(ns + "exampleEmbeddedTagName" select c).First();

    // obtain an attribute from an element
    XAttribute attribute = element.Attribute("exampleAttributeName");
}

使用这些功能,我可以解析XML文件中的任何元素和任何属性,根本没有问题!


8

如果您使用的是.NET 2.0,请尝试XmlReader及其子类XmlTextReaderXmlValidatingReader。它们提供了一种快速,轻量级(内存使用等),仅向前的方式来解析XML文件。

如果需要XPath功能,请尝试XPathNavigator。如果您需要整个文档存储在内存中,请尝试XmlDocument


7

在Addition中,您可以通过以下方式使用XPath选择器(选择特定节点的简便方法):

XmlDocument doc = new XmlDocument();
doc.Load("test.xml");

var found = doc.DocumentElement.SelectNodes("//book[@title='Barry Poter']"); // select all Book elements in whole dom, with attribute title with value 'Barry Poter'

// Retrieve your data here or change XML here:
foreach (XmlNode book in nodeList)
{
  book.InnerText="The story began as it was...";
}

Console.WriteLine("Display XML:");
doc.Save(Console.Out);

文档


6

我不确定是否存在“解析XML的最佳实践”。有许多适合不同情况的技术。使用哪种方式取决于具体情况。

你可以去的LINQ to XMLXmlReaderXPathNavigator或者甚至正则表达式。如果您详细说明您的需求,我可以尝试提出一些建议。


3
xml的正则表达式。你这个怪物。
将于

3

您可以使用此库解析XML System.Xml.Linq。以下是我用来解析XML文件的示例代码

public CatSubCatList GenerateCategoryListFromProductFeedXML()
{
    string path = System.Web.HttpContext.Current.Server.MapPath(_xmlFilePath);

    XDocument xDoc = XDocument.Load(path);

    XElement xElement = XElement.Parse(xDoc.ToString());


    List<Category> lstCategory = xElement.Elements("Product").Select(d => new Category
    {
        Code = Convert.ToString(d.Element("CategoryCode").Value),
        CategoryPath = d.Element("CategoryPath").Value,
        Name = GetCateOrSubCategory(d.Element("CategoryPath").Value, 0), // Category
        SubCategoryName = GetCateOrSubCategory(d.Element("CategoryPath").Value, 1) // Sub Category
    }).GroupBy(x => new { x.Code, x.SubCategoryName }).Select(x => x.First()).ToList();

    CatSubCatList catSubCatList = GetFinalCategoryListFromXML(lstCategory);

    return catSubCatList;
}

1

您可以使用ExtendedXmlSerializer进行序列化和反序列化。

安装 您可以从nuget安装ExtendedXmlSerializer 或运行以下命令:

Install-Package ExtendedXmlSerializer

序列化:

ExtendedXmlSerializer serializer = new ExtendedXmlSerializer();
var obj = new Message();
var xml = serializer.Serialize(obj);

反序列化

var obj2 = serializer.Deserialize<Message>(xml);

.NET中的标准XML序列化器非常有限。

  • 不支持对具有循环引用的类或具有接口属性的类进行序列化,
  • 不支持字典,
  • 没有读取旧版XML的机制,
  • 如果要创建自定义序列化程序,则您的类必须继承自IXmlSerializable。这意味着您的课程将不是POCO课程,
  • 不支持IoC。

ExtendedXmlSerializer可以完成更多任务。

ExtendedXmlSerializer支持.NET 4.5或更高版本以及.NET Core。您可以将其与WebApi和AspCore集成。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.