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

时间:2012-10-03 10:26:49

标签: c# xml linq

我有一个具有以下结构的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>

我想解析Xml文件,并打印出依赖“flow”。

例如:

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

目的是创建一个将安装应用程序的“序列”,命令应存储在Xml文件中。包可能有依赖关系。

我可以使用Linq来解决这个问题吗?

我不需要一个完整的解决方案,只需要一个正确方向的提示。

1 个答案:

答案 0 :(得分:0)

简单的答案是肯定的。也使用XPath。

  

使用System.Xml.XPath;

你可以使用这样的递归来设置它:

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);
    }
}

抱歉,我不能很好地写提示。我没有测试或编译它,所以可能需要一些调整。

没有捕获无限循环。如果任何子依赖引用了upline包,那么将会有一个无限循环。

这也是非常低效的,如果每个包都记得它的家属是什么等,它会更快。为此,您必须为每个包创建一个类。如果您要解析的文件非常大,那么您应该采用这种方法。带有密钥名称的Dictionary<string, PackageClass>可以提供帮助。