如何解析XML文件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何解析XML文件相关的知识,希望对你有一定的参考价值。

参考技术A

1)DOM(JAXP Crimson解析器) 
        DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。DOM以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。

2)SAX

        SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快许多。 
   选择DOM还是选择SAX? 对于需要自己编写代码来处理XML文档的开发人员来说,  选择DOM还是SAX解析模型是一个非常重要的设计决策。 DOM采用建立树形结构的方式访问XML文档,而SAX采用的事件模型。 
  DOM解析器把XML文档转化为一个包含其内容的树,并可以对树进行遍历。用DOM解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用DOM解析器的时候需要处理整个XML文档,所以对性能和内存的要求比较高,尤其是遇到很大的XML文件的时候。由于它的遍历能力,DOM解析器常用于XML文档需要频繁的改变的服务中。 
  SAX解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag。特别是当开发人员只需要处理文档中所包含的部分数据时,SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。

xml文件:  
<?xml version="1.0" encoding="utf-8" ?>   
<Result>  
   <VALUE>  
       <NO DATE="2005">A1</NO>  
       <ADDR>GZ</ADDR>  
   </VALUE>  
   <VALUE>  
       <NO DATE="2004">A2</NO>  
       <ADDR>XG</ADDR>  
  </VALUE>  
</Result>  
  
1)DOM  
import java.io.*;  
import java.util.*;  
import org.w3c.dom.*;  
import javax.xml.parsers.*;  
  
public class MyXMLReader   
 public static void main(String arge[])  
  
  long lasting =System.currentTimeMillis();   
  try    
   File f=new File("data_10k.xml");   
   DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();   
   DocumentBuilder builder=factory.newDocumentBuilder();   
   Document doc = builder.parse(f);   
   NodeList nl = doc.getElementsByTagName("VALUE");   
   for (int i=0;i<nl.getLength();i++)   
    System.out.print("车牌号码:" + doc.getElementsByTagName("NO").item(i).getFirstChild().getNodeValue());   
    System.out.println("车主地址:" + doc.getElementsByTagName("ADDR").item(i).getFirstChild().getNodeValue());   
      
  catch(Exception e)   
   e.printStackTrace();   
  
  
2)SAX  
  
import org.xml.sax.*;  
import org.xml.sax.helpers.*;  
import javax.xml.parsers.*;  
  
public class MyXMLReader extends DefaultHandler   
  
 java.util.Stack tags = new java.util.Stack();   
 public MyXMLReader()    
  super();  
     
  
 public static void main(String args[])    
  long lasting = System.currentTimeMillis();   
  try    
   SAXParserFactory sf = SAXParserFactory.newInstance();   
   SAXParser sp = sf.newSAXParser();   
   MyXMLReader reader = new MyXMLReader();   
   sp.parse(new InputSource("data_10k.xml"), reader);   
   catch (Exception e)    
   e.printStackTrace();   
    
  
  System.out.println("运行时间:" + (System.currentTimeMillis() - lasting) + "毫秒");   
  public void characters(char ch[], int start, int length) throws SAXException    
  String tag = (String) tags.peek();   
  if (tag.equals("NO"))     
   System.out.print("车牌号码:" + new String(ch, start, length));  
      
    if (tag.equals("ADDR"))    
  System.out.println("地址:" + new String(ch, start, length));  
      
     
  
  public void startElement(String uri,String localName,String qName,Attributes attrs)    
  tags.push(qName);  

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

【中文标题】如何解析 XML 文件? [关闭]【英文标题】:How does one parse XML files? [closed] 【发布时间】:2010-09-08 12:32:11 【问题描述】:

有没有简单的C#解析XML文件的方法?如果有,是什么?

【问题讨论】:

你可以使用这个实现:***.com/a/34813985/5784646 好的,我重新打开了这个。副本是一个 XML Reader 解决方案,因为这是关于解析 XML 文件的。 可能的重复可以在问题edithistory ps @GeorgeStocker中看到 @JeremyThompson 这是重复的原因之一是另一个问题的答案要好得多。最重要的答案是一个简单的“仅链接”答案是没有用的。 @GeorgeStocker 问题的不同之处足以共存,并且都有很好的答案,而且被接受的问题使用不同的技术。这就是为什么我投票让我们保持开放,我知道这个被接受的只是链接,但它是 MSDN 并且是在不可接受之前编写的,希望重新开放的副作用是让 Jon 振作一点,阅读他的个人资料。无论如何欢呼。 【参考方案1】:

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

这里有一些例子:

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);

此外,还有一些 other methods 可以使用。例如,here。而且我认为没有一种最好的方法可以做到这一点。你总是需要自己去选择,什么最适合你。

【讨论】:

+1 用于提及 XmlDocument,在某些情况下这比序列化接口方便得多。如果您在寻找一个特定元素,您可以使用索引器访问子元素:xmlDoc["Root"],这些可以链接起来:xmlDoc["Root"]["Folder"]["Item"]层次结构(尽管验证这些元素确实存在是明智的) InnerText 在这里获取该节点的值,并与子节点的所有值连接 - 对吧?想要的东西似乎很奇怪。 有女性朋友名单的程序员?恶作剧! @E.vanPutten 不在这个时代。这不是书呆子的复仇 @DonCheadle 如果您不希望那里有任何子节点,那么InnerText 将只返回节点值 - 这就是我(可能还有其他人)阅读这个问题)首先解析 XML 以查找。【参考方案2】:

如果您使用 .NET 3.5 或更高版本,我会使用 LINQ to XML。

【讨论】:

我尝试使用它,但无法弄清楚如何获得像我的 XML 中某个元素的标识符值这样简单的东西(或者如何通过标识符获取元素,就此而言) )。相比之下,使用 XmlDocument 我可以轻松做到这一点。【参考方案3】:

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

MSDN 上有an introductory article about XML Serialisation。

性能提示:构造XmlSerializer 的成本很高。如果您打算解析/写入多个 XML 文件,请保留对您的 XmlSerializer 实例的引用。

【讨论】:

见codeproject.com/KB/cs/xsdtidy.aspx和blog.dotnetwiki.org/XsdTidyXSDMappingBeautifier.aspx 很好的例子是微软这个例子中间的“采购订单例子”。 msdn.microsoft.com/en-us/library/58a18dwa.aspx。您不必创建架构——您的 c# 类就是架构,装饰有 C# 属性。【参考方案4】:

如果您正在处理大量数据(数兆字节),那么您希望使用 XmlReader 流式解析 XML。

任何其他内容(XPathNavigatorXElementXmlDocument 甚至 XmlSerializer,如果您保留完整生成的对象图)将导致 high memory usage 以及非常缓慢的加载时间。

当然,如果你无论如何都需要内存中的所有数据,那么你可能没有太多选择。

【讨论】:

【参考方案5】:

使用XmlTextReaderXmlReaderXmlNodeReaderSystem.Xml.XPath 命名空间。还有(XPathNavigatorXPathDocumentXPathExpressionXPathnodeIterator)。

通常XPath 使阅读 XML 变得更容易,这正是您可能正在寻找的。​​p>

【讨论】:

仅供参考,您不应使用new XmlTextReader()new XmlTextWriter()。自 .NET 2.0 以来,它们已被弃用。请改用XmlReader.Create()XmlWriter.Create()【参考方案6】:

我最近刚被要求处理一个涉及解析 XML 文档的应用程序,我同意 Jon Galloway 的观点,即在我看来,基于 LINQ to XML 的方法是最好的。不过,我确实需要挖掘一些东西才能找到可用的示例,所以事不宜迟,这里有一些!

欢迎任何 cmets,因为此代码有效,但可能并不完美,我想了解有关为该项目解析 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 文件中的任何元素和任何属性,一点问题都没有!

【讨论】:

【参考方案7】:

此外,您可以通过以下方式使用 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);

the documentation

【讨论】:

【参考方案8】:

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

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

【讨论】:

【参考方案9】:

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

您可以使用LINQ to XML、XmlReaderXPathNavigator 甚至正则表达式。如果您详细说明您的需求,我可以尝试提供一些建议。

【讨论】:

xml 的正则表达式。你这个怪物。【参考方案10】:

您可以使用此库 System.Xml.Linq 解析 XML。下面是我用来解析 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;

【讨论】:

【参考方案11】:

可以使用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 集成。

【讨论】:

【参考方案12】:

您可以使用 XmlDocument 并从属性中操作或检索数据,您可以 Linq 到 XML 类。

【讨论】:

以上是关于如何解析XML文件的主要内容,如果未能解决你的问题,请参考以下文章

解析xml文件,如何动态的封装成一个java类

如何使用 QXmlStreamReader 解析包含对其他 XML 文件的引用的 XML 文件?

如何使用 System.Xml.Linq 解析 xml 文件

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

如何在文档中下载和保存 xml,然后如何从文档中解析 xml 文件?

如何解析XML文件