【问题标题】:Parsing XML file using C#?使用 C# 解析 XML 文件?
【发布时间】:2013-05-29 21:42:11
【问题描述】:

我是 XML 和 C# 的新手;我试图找到一种方法来有效地解析给定的 xml 文件以检索相关的数值,基于 "proj_title" value=heat_run 或任何其他可能的值。例如,计算特定测试运行的持续时间(proj_end val-proj_start val)。

ex.xml:

<proj ID="2">
      <proj_title>heat_run</proj_title>
      <proj_start>100</proj_start>
      <proj_end>200</proj_end>
</proj>

... 我们不能按项目 ID 搜索,因为这个值在测试运行之间不是固定的。上面的文件很大:~8mb,并且有 ~2000 个标签,名称为 proj_title。有没有一种有效的方法可以首先找到带有 proj_title="heat_run" 的所有标签名称,然后使用 C# 检索这个特定 proj_title 的 proj 开始和结束值??

这是我当前的 C# 代码:

public class parser
{
     public static void Main()
     {
         XmlDocument xmlDoc= new XmlDocument();
         xmlDoc.Load("ex.xml");

         //~2000 tags w/ proj_title
         //any more efficient way to just look for proj_title="heat_run" specifically?
         XmlNodeList heat_run_nodes=xmlDoc.GetElementsByTagName("proj_title");
     }
}    

【问题讨论】:

  • 我很幸运地使用了 XML 序列化,您可以将 XML 转换为对象...This Link 可以帮助您

标签: c# xml xml-parsing tags


【解决方案1】:

您可以使用 XPath 查找所有匹配的节点,例如:

XmlNodeList matches = xmlDoc.SelectNodes("proj[proj_title='heat_run']")

matches 将包含与标准匹配的所有proj 节点。了解有关 XPath 的更多信息:http://www.w3schools.com/xsl/xpath_syntax.asp

MSDN Documentation on SelectNodes

【讨论】:

    【解决方案2】:

    按照现代标准,8MB 确实不是很大。我个人会使用 LINQ to XML:

    XDocument doc = XDocument.Load("ex.xml");
    var projects = doc.Descendants("proj_title")
                      .Where(x => (string) x == "heat_run")
                      .Select(x => x.Parent) // Just for simplicity
                      .Select(x => new {
                                  Start = (int) x.Element("proj_start"),
                                  End = (int) x.Element("proj_end")
                              });
    
    foreach (var project in projects)
    {
        Console.WriteLine("Start: {0}; End: {1}", project.Start, project.End);
    }
    

    (显然根据您自己的要求进行调整 - 根据问题,您需要做什么并不清楚。)

    替代查询:

    var projects = doc.Descendants("proj")
                      .Where(x => (string) x.Element("proj_title") == "heat_run")
                      .Select(x => new {
                                  Start = (int) x.Element("proj_start"),
                                  End = (int) x.Element("proj_end")
                              });
    

    【讨论】:

    • 这对我帮助很大!我只需要再添加 1 个 Where 条件。例如,LINQ/C# 中是否有一个选项可以引用 x 的祖先?比如 Where (x => (string) x== "heat_run" && (string) x.Ancestor=="heat_test")。我试过了,还是不行?
    • @jerryh91:你可以使用Parent,但我通常会反过来 - 找到有特定孩子的父母。
    【解决方案3】:

    使用 XDocument 并使用 LINQ api。 http://msdn.microsoft.com/en-us/library/bb387098.aspx

    如果尝试后性能不如预期,则必须寻找 sax 解析器。 Sax 解析器不会将整个文档加载到内存中,而是尝试对内存中的所有内容应用 xpath 表达式。它在事件驱动的方法中更有效,在某些情况下,它可以更快,并且不会使用太多内存。

    那里可能有 .NET 的 sax 解析器,我自己没有将它们用于 .NET,但我为 C++ 使用过。

    【讨论】:

      猜你喜欢
      • 2021-03-27
      • 2015-03-14
      • 2023-03-06
      • 2013-07-22
      • 1970-01-01
      • 2012-01-01
      • 2023-04-07
      相关资源
      最近更新 更多