简体   繁体   English

使用Linq搜索Xml文件,获取与子节点匹配的节点

[英]Search Xml file with Linq, get nodes that match to subnodes

I have a Xml file with the following structure: 我有一个具有以下结构的Xml文件:

<Packages>
    <Package>
        <Name>Package1</Name>
        <Dependencies>
            <Dependency>Package2 </Dependency>
        </Dependencies>
    </Package>
    <Package>
        <Name>Package2</Name>
        <Dependencies>
            <Dependency>Package3</Dependency>
        </Dependencies>
    </Package>
    <Package>
        <Name>Package3</Name>
        <Dependencies />
    </Package>
</Packages>

I want to parse the Xml file, and print out the dependency "flow". 我想解析Xml文件,并打印出依赖项“流”。

For example: 例如:

Package1 -> 
  Package2 ->
    Package3
Package2 ->
  Package3
Package3

The purpose is to create a "sequence" that will install applications, the commands should be stored in a Xml file. 目的是创建将安装应用程序的“序列”,命令应存储在Xml文件中。 A package could have dependencies. 程序包可能具有依赖性。

Can I use Linq to solve this problem? 我可以使用Linq解决此问题吗?

I don't need a complete solution, just a hint in right direction. 我不需要一个完整的解决方案,只是在正确方向上提供了一个提示。

The simple answer is yes you can. 简单的答案是可以。 Using XPath as well. 也使用XPath。

using System.Xml.XPath; 使用System.Xml.XPath;

You could set it up using recursion like this: 您可以使用递归来设置它,如下所示:

XElement root = XElement.Load(file); // or .Parse(xmlString);
foreach(XElement package in root.Descendants("Package"))
{
    DoPackage(package, 0);
}

void DoPackage(XElement package, int level)
{
    StringBuilder name = new StringBuilder();
    for(int i = 0; i < level; i++) name.Append("  ");
    name.Append(package.Element("Name").Value);
    var dependencies = package.Descendants("Dependency");
    if(dependencies.Count() > 0)
        name.Append(" ->");
    Console.WriteLine(name.ToString());
    foreach(XElement dependent in dependencies)
    {
        string dependentName = dependent.Value;
        XElement dependentElement = 
            package.XPathSelectElement("//Package[Name='"+dependentName+"']");
        DoPackage(dependentElement, level + 1);
    }
}

Sorry, I can't write hints very well. 抱歉,我不能很好地编写提示。 I didn't test or compile this, so it may need some tweaking. 我没有测试或编译它,因此可能需要进行一些调整。

There is no catching for infinite loops. 无限循环是没有用的。 If any child dependent refers to an upline package, then there will be an infinite loop. 如果有任何依赖于子项的人引用上线软件包,则将存在无限循环。

This is also very inefficient, it would be faster if each package remembered what its dependents were and so on. 这也是非常低效的,如果每个程序包记住其依赖项等等,将会更快。 For that you would have to create a class for each package. 为此,您必须为每个包创建一个类。 If the file you are parsing is very big, you should go with this approach. 如果要分析的文件很大,则应采用这种方法。 A Dictionary<string, PackageClass> with the name for the key could help. 具有关键字名称的Dictionary<string, PackageClass>可能会有所帮助。

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

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