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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/108010/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 14:16:07  来源:igfitidea点击:

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

提问by James Skemp

Greetings.

你好。

I'm looking for a way to parse a number of XML files in a particular directory with ASP.NET (C#). 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.

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

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'.

给我所有标题为“标题 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 文件时执行此操作的示例,而不是在有多个 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

~詹姆斯

采纳答案by naspinski

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 规则!

回答by Per Hornsh?j-Schierbeck

回答by chakrit

You might want to create your own iterator class that iterate over those files.

您可能希望创建自己的迭代器类来迭代这些文件。

Say, make a 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:

比如说,创建一个 XMLContentEnumerator : IEnumerable。这将遍历特定目录中的文件并解析其内容,然后您就可以进行正常的 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.

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

回答by Mattio

Here's one way using 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.

这是使用 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();
}