使用ASP.NET(C#)解析多个XML文件并返回带有特定元素的文件

时间:2020-03-06 14:28:58  来源:igfitidea点击:

你好。

我正在寻找一种使用ASP.NET(C#)解析特定目录中许多XML文件的方法。我希望能够从特定元素返回内容,但是在此之前,需要找到在元素之间具有特定值的内容。

示例XML文件1:

<file>
    <title>Title 1</title>
    <someContent>Content</someContent>
    <filter>filter</filter>
</file>

示例XML文件2:

<file>
    <title>Title 2</title>
    <someContent>Content</someContent>
    <filter>filter, different filter</filter>
</file>

示例案例1:

给我所有具有"过滤器"过滤器的XML。

示例案例2:

给我所有标题为"标题1"的XML。

看起来,使用LINQ似乎应该可以实现,但是我仅看到了有关在一个XML文件时如何执行此操作的示例,而在存在多个XML文件时(例如在这种情况下)却没有。

我希望这是在服务器端完成的,这样我就可以在那端进行缓存了。

可以使用任何版本的.NET Framework的功能。

谢谢!

〜詹姆斯

解决方案

使用XPath?
http://www.w3schools.com/XPath/default.asp

我们可能想要创建自己的迭代器类,以对这些文件进行迭代。

说,做一个XMLContentEnumerator:IEnumerable。它将遍历特定目录中的文件并解析其内容,然后我们可以进行常规的LINQ过滤查询,例如:

var xc = new XMLContentEnumerator(@"C:\dir");

var filesWithHello = xc.Where(x => x.title.Contains("hello"));

我没有提供完整示例的环境,但这应该给出一些想法。

如果我们使用的是.Net 3.5,则使用LINQ非常简单:

//get the files
XElement xe1 = XElement.Load(string_file_path_1);
XElement xe2 = XElement.Load(string_file_path_2);

//Give me all XML that has a filter of 'filter'.
var filter_elements1 = from p in xe1.Descendants("filter") select p;
var filter_elements2 = from p in xe2.Descendants("filter") select p;
var filter_elements = filter_elements1.Union(filter_elements2);

//Give me all XML that has a title of 'Title 1'.
var title1 = from p in xe1.Descendants("title") where p.Value.Equals("Title 1") select p;
var title2 = from p in xe2.Descendants("title") where p.Value.Equals("Title 1") select p;
var titles = title1.Union(title2);

所有这些都可以写为简写,并且总共只有4行就可以得到结果:

XElement xe1 = XElement.Load(string_file_path_1);
XElement xe2 = XElement.Load(string_file_path_2);
var _filter_elements = (from p1 in xe1.Descendants("filter") select p1).Union(from p2 in xe2.Descendants("filter") select p2);
var _titles = (from p1 in xe1.Descendants("title") where p1.Value.Equals("Title 1") select p1).Union(from p2 in xe2.Descendants("title") where p2.Value.Equals("Title 1") select p2);

这些都是IEnumerable列表,因此它们非常易于使用:

foreach (var v in filter_elements)
    Response.Write("value of filter element" + v.Value + "<br />");

LINQ规则!

这是使用Framework 2.0的一种方法。我们可以通过使用正则表达式而不是简单的字符串测试来使它更干净。如果需要提高性能,也可以尝试编译XPath表达式。

static void Main(string[] args)
{
    string[] myFiles = { @"C:\temp\XMLFile1.xml", 
                         @"C:\temp\XMLFile2.xml", 
                         @"C:\temp\XMLFile3.xml" };
    foreach (string file in myFiles)
    {
        System.Xml.XPath.XPathDocument myDoc = 
            new System.Xml.XPath.XPathDocument(file);
        System.Xml.XPath.XPathNavigator myNav = 
            myDoc.CreateNavigator();

        if(myNav.SelectSingleNode("/file/filter[1]") != null &&
            myNav.SelectSingleNode("/file/filter[1]").InnerXml.Contains("filter"))
            Console.WriteLine(file + " Contains 'filter'");

        if (myNav.SelectSingleNode("/file/title[1]") != null &&
            myNav.SelectSingleNode("/file/title[1]").InnerXml.Contains("Title 1"))
            Console.WriteLine(file + " Contains 'Title 1'");
    }

    Console.ReadLine();
}