简体   繁体   English

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

[英]Parse multiple XML files with ASP.NET (C#) and return those with particular element

Greetings. 问候。

I'm looking for a way to parse a number of XML files in a particular directory with ASP.NET (C#). 我正在寻找一种方法,用ASP.NET(C#)解析特定目录中的大量XML文件。 I'd like to be able to return content from particular elements, but before that, need to find those that have a certain value between an element. 我希望能够从特定元素返回内容,但在此之前,需要找到元素之间具有特定值的内容。

Example XML file 1: 示例XML文件1:

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

Example XML file 2: 示例XML文件2:

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

Example case 1: 示例案例1:

Give me all XML that has a filter of 'filter'. 给我所有具有'过滤器'过滤器的XML。

Example case 2: 案例2:

Give me all XML that has a title of 'Title 1'. 给我所有标题为“Title 1”的XML。

Looking, it seems this should be possible with LINQ, but I've only seen examples on how to do this when there is one XML file, not when there are multiples, such as in this case. 看起来,这似乎应该可以用LINQ,但我只看到有关如何在有一个XML文件时执行此操作的示例,而不是在存在多个时,例如在这种情况下。

I would prefer that this be done on the server-side, so that I can cache on that end. 我希望这可以在服务器端完成,这样我就可以在那一端缓存。

Functionality from any version of the .NET Framework can be used. 可以使用任何版本的.NET Framework的功能。

Thanks! 谢谢!

~James 〜詹姆斯

If you are using .Net 3.5, this is extremely easy with LINQ: 如果您使用的是.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);

This can all be written shorthand and get you your results in just 4 lines total: 这一切都可以写成速记,只需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);

These will all be IEnumerable lists, so they are super easy to work with: 这些都是IEnumerable列表,因此它们非常容易使用:

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

LINQ rules! LINQ规则!

You might want to create your own iterator class that iterate over those files. 您可能希望创建自己的迭代器类来迭代这些文件。

Say, make a XMLContentEnumerator : IEnumerable. 比如说,制作一个XMLContentEnumerator:IEnumerable。 that would iterate over files in a specific directory and parse its content, and then you would be able to make a normal LINQ filtering query such as: 这将迭代特定目录中的文件并解析其内容,然后您将能够进行正常的LINQ过滤查询,例如:

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

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

I don't have the environment to provide a full example, but this should give some ideas. 我没有提供完整示例的环境,但这应该提供一些想法。

Here's one way using Framework 2.0. 这是使用Framework 2.0的一种方式。 You can make this cleaner by using regular expressions rather than a simple string test. 您可以使用正则表达式而不是简单的字符串测试来使其更清晰。 You can also try compiling your XPath expressions if you need to squeeze more for performance. 如果您需要为了提高性能,还可以尝试编译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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM