【问题标题】:How do I search through an XML file recursively?如何递归搜索 XML 文件?
【发布时间】:2020-02-24 11:46:07
【问题描述】:

我想在 XML 文件中搜索名称为“Reference”的节点。 这些节点的内部文本是其他 xml 文件。我还想为相同的节点(“参考”)解析这些 xml 文件。

我使用一些方法来设置我找到的引用的名称和路径,但我不知道如何递归。

类,我在其中搜索并设置在 XML 中找到的引用的名称和路径

public class SetReferences
{
    public SetReferences(string[] args)
    {
        XmlDocument doc = new XmlDocument();
        doc.Load(args[0]);
        XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
        ns.AddNamespace("msbld", "http://schemas.microsoft.com/developer/msbuild/2003");
        XmlNodeList nodelist = doc.SelectNodes("//msbld:Reference", ns);
        foreach (XmlNode node in nodelist)
        {

            var file = new FileInfo(node.InnerText);
            AnalyzedAssembly analyzedAssembly = new AnalyzedAssembly
                {
                    AssemblyName = file.Name,
                    AssemblyFile = file
                };


                Console.WriteLine(analyzedAssembly.AssemblyName);
                Console.WriteLine(analyzedAssembly.AssemblyFile);
        }
    }
}


public class AnalyzedAssembly
{
    public string AssemblyName { get; set; }
    public FileInfo AssemblyFile { get; set; }        
    public List<AnalyzedAssembly> ChildDepencies { get; } = new List<AnalyzedAssembly>();

}

这是我的主线

class Program
{
    static void Main(string[] args)
    {
        new SetReferences(args);

        Console.WriteLine("\nPress any key to exit.");
        Console.ReadKey();
    }

}

XML 文件如下所示

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Reference Include="DataMatrix.net, Version=1.0.0.0>
      <HintPath>..\packages\DataMatrix.net.0.4.2\lib\20\DataMatrix.net.dll</HintPath>
    </Reference>
    <Reference Include="Devart.Data, Version=5.0.1289.0>
      <HintPath>..\..\lib\ExtLib\DevArt\Devart.Data.dll</HintPath>
    </Reference>

我希望列出所有参考文献。每个参考都存在一个 xml 文件。我想在这些中搜索“References of the Reference”。

现在我得到了上面这个 XML 的所有引用,但是搜索不是递归的。

背景是我必须在项目中包含的所有引用的源代码中搜索 SQL 语句。为此,我首先需要所有参考资料。

【问题讨论】:

    标签: c# xml recursion search


    【解决方案1】:

    我确实在修改我的答案

    要实现递归算法,您需要建立所谓的递归枢轴,即包含自身实例的对象。 在这种情况下,您是 XMLFile

    所以你将拥有: 1) 将肯定接受表示文件名的字符串的归纳方法 2) 将解析文件并将结果存储在集合中的递归方法的主体 3)实际的递归调用 4) 结果打印

    看起来像这样的东西

    public SetReferences(String[] args)
    {
        List<AnalyzedAssembly> analyzedAssembly;
        analyzedAssembly.add(buildAnalyzedAssembly(args[0]);
        analyzedAssembly.addAll(recursion(args[0])); // Root XML file
    
        // Print result by using analyzedAssembly
    }
    
    private List<AnalyzedAssembly> recursion(String xmlFileName) {
        List<AnalyzedAssembly> analyzedAssembly = new ArrayList<>();
        XmlDocument doc = new XmlDocument();
        XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
        ns.AddNamespace("msbld", "http://schemas.microsoft.com/developer/msbuild/2003");
        XmlNodeList nodelist = doc.SelectNodes("//msbld:Reference", ns);
        foreach (XmlNode node in nodelist) {
            // Create an instance of AnalyzedAssembly and perform recursive call
            analyzedAssembly.add(node.InnerText); // Use XML file name in node
            analyzedAssembly.addAll(recursion(node.InnerText));
    
        }
        // Finally return list
        return analyzedAssembly;
    }
    
    private AnalyzedAssembly buildAnalyzedAssembly(String xmlFileName) {
        var file = new FileInfo(xmlFileName); // Build file with the name given in input
        AnalyzedAssembly analyzedAssembly = new AnalyzedAssembly
            {
                AssemblyName = file.Name,
                AssemblyFile = file
            };
        return analyzedAssembly;
    }
    

    【讨论】:

    • 如何使用 for 循环来做到这一点?
    • 嘿@idontcare 我修改了我的回复,我看错了你问题中的第一句话。
    • 经过几次定制后,它与这个解决方案一起工作。非常感谢!
    【解决方案2】:

    由于我不知道这些方法的确切语法,我只能提供一些描述...... 因此,尝试将实际搜索分离到一个方法中,例如 bar,该方法将节点列表作为输入,与找到的节点一起工作,将内部文本处理为节点并调用自身所有满足条件的子节点。 所以,你先做好所有的准备,然后调用一次分离的方法bar。

    编辑: 我没有遵守代码或任何内容,因此可能存在大量错误。我认为,这可能有助于更进一步。

    class Program
    {
        static void Main(string[] args)
        {
            new SetReferences(args);
    
            Console.WriteLine("\nPress any key to exit.");
            Console.ReadKey();
        }
    
        private SetReferences(string[] args)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(args[0]);
            XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
            ns.AddNamespace("msbld", "http://schemas.microsoft.com/developer/msbuild/2003");
            XmlNodeList nodelist = doc.SelectNodes("//msbld:Reference", ns);
            HandleNodes(nodelist);
        }
    
        private HandleNodes(XmlNodeList[] nodes)
        {
            foreach (XmlNode node in nodelist)
            {
    
                var file = new FileInfo(node.InnerText);
                AnalyzedAssembly analyzedAssembly = new AnalyzedAssembly
                {
                    AssemblyName = file.Name,
                    AssemblyFile = file
                };
    
    
                Console.WriteLine(analyzedAssembly.AssemblyName);
                Console.WriteLine(analyzedAssembly.AssemblyFile);
    
                // Get a new nodelist from the inner XML
                // and call HandleNodes on this new nodelist here.
            }
        }
    }
    
    public class AnalyzedAssembly
    {
        public string AssemblyName { get; set; }
        public FileInfo AssemblyFile { get; set; }        
        public List<AnalyzedAssembly> ChildDepencies { get; } = new List<AnalyzedAssembly>();
    
    }
    

    【讨论】:

    • 谢谢!但是我从哪里得到一个新的节点列表呢?在我的第一个 xml 参考中是参考 xml 的路径。而且这个路径是FileInfo格式的
    • 你能提供一个这样的 XML 的小例子吗?我不确定我是否理解正确...
    • 已将其添加到问题中
    • 好的,正如@sergio-arrighi 在另一个答案中提到的那样,您的结构已经是平坦的。你看过这个网站吗? link
    • 不抱歉,我确实看错了问题的第一句话:'(我也更新了我的答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-24
    • 2012-06-15
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    • 2021-01-25
    • 1970-01-01
    相关资源
    最近更新 更多