【问题标题】:c# recursion on an xml file containing links to dozens of other xml files that i want to loop through entirelyc#递归一个xml文件,其中包含指向我想完全循环的几十个其他xml文件的链接
【发布时间】:2017-02-01 23:22:07
【问题描述】:

我正在尝试弄清楚如何创建一个递归函数来读取初始 xml 文档,如下所示。

这些节点中的每个 href 属性都是一个链接。 "" + 那个 href 值。

递归循环将为其中的每一个打开一个 xdoc。

请注意,有些说是文件夹,有些说是视频。我想为每个文件夹创建一个文件夹,为每个视频列出该 href 的文本文件。几乎与递归文件夹/文件树的经典递归示例相同。

有什么建议吗?我试过做一组foreach循环,将hrefs添加到列表中,然后遍历它们,但无论我尝试什么,我从来没有正确的文件夹结构,如果我写一个文件,我总是会用任何东西覆盖它下一个。

作为参考,它来自 playon 应用程序,这是 netflix 的“最近添加”列表。

这是一个简单的路径示例,来自:netflix 用户 -> 我的列表 -> 电视节目 -> 电视节目季节 ->

文件夹树的开始

<group name="Netflix" href="/data/data.xml?id=netflix" type="folder" art="/images/provider.png?id=netflix" searchable="true" id="netflix" childs="0" category="4099">
<group name="Taylor" href="/data/data.xml?id=netflix-73b43a5abf0b4d6086c0a6a2f11200ee" type="folder" childs="0"/>
<group name="Courtney" href="/data/data.xml?id=netflix-00a010f3321f4ca0ae7592a0126995e4" type="folder" childs="0"/>
<group name="Kids" href="/data/data.xml?id=netflix-76d20d377e1f49af9848b2335cb9199f" type="folder" childs="0"/>
<group name="Playback Options" href="/data/data.xml?id=netflix-6b2f5118e04e4072bfe48ab298d4a91f" type="folder" childs="0" art="/images/poster.jpg?id=netflix-6b2f5118e04e4072bfe48ab298d4a91f&size=tiny"/>
</group>

Netflix/Taylor("localhost:54479" + href 属性值)

<group name="Taylor" href="/data/data.xml?id=netflix-73b43a5abf0b4d6086c0a6a2f11200ee" type="folder">
<group name="My List" href="/data/data.xml?id=netflix-98fad8d5a8f348a5b0cb3d7fe6e81ea9" type="folder" childs="0"/>
<group name="Continue Watching" href="/data/data.xml?id=netflix-755b5fb0bb4d4ccab84f92193b7ae10e" type="folder" childs="0"/>
<group name="Browse Genres" href="/data/data.xml?id=netflix-ebc7ba3576dd4cc38acc7478bab3a4ca" type="folder" childs="0"/>
<group name="Just for Kids" href="/data/data.xml?id=netflix-970a14c27f48488188b94d5734797415" type="folder" childs="0"/>
<group name="Top Picks for Taylor" href="/data/data.xml?id=netflix-745bb4c1d2ce43a5aaa24a25bc78f881" type="folder" childs="0"/>
<group name="Recently Added" href="/data/data.xml?id=netflix-0ce59d5a759f4c5c93df8428489c3cff" type="folder" childs="0"/>
<group name="Popular on Netflix" href="/data/data.xml?id=netflix-60802588a871490fa73f13c0ba673a80" type="folder" childs="0"/>
<group name="Suggestions For You" href="/data/data.xml?id=netflix-9491e584db7b4c0c918df7bfbb0e1fe4" type="folder" childs="0"/>
</group>

NetFlix/Taylor/Mylist("localhost:54479"+'my list'节点的href属性值)

<group name="My List" href="/data/data.xml?id=netflix-98fad8d5a8f348a5b0cb3d7fe6e81ea9" type="folder">
<group name="Africa" href="/data/data.xml?id=netflix-1947c3b0dc91480c8d31f0bfe60194ab" type="folder" childs="0" art="/images/poster.jpg?id=netflix-1947c3b0dc91480c8d31f0bfe60194ab&size=tiny"/>
<group name="Animals Gone Wild" href="/data/data.xml?id=netflix-0793a52b83d746bb8009de611ca48a63" type="folder" childs="0" art="/images/poster.jpg?id=netflix-0793a52b83d746bb8009de611ca48a63&size=tiny"/>
<group name="Ascension" href="/data/data.xml?id=netflix-f6945330c90443f6a889edee09ecd977" type="folder" childs="0" art="/images/poster.jpg?id=netflix-f6945330c90443f6a889edee09ecd977&size=tiny"/>
<group name="The Blue Planet: A Natural History of the Oceans" href="/data/data.xml?id=netflix-b811b457743f4cbbaffc066e01d3e5b5" type="folder" childs="0" art="/images/poster.jpg?id=netflix-b811b457743f4cbbaffc066e01d3e5b5&size=tiny"/>
<group name="Brain Games" href="/data/data.xml?id=netflix-9311dc81e85c4f20a192095c23fd3bf2" type="folder" childs="0" art="/images/poster.jpg?id=netflix-9311dc81e85c4f20a192095c23fd3bf2&size=tiny"/>
<group name="Breaking Bad" href="/data/data.xml?id=netflix-26775c743497400995f6440ef543c99d" type="folder" childs="0" art="/images/poster.jpg?id=netflix-26775c743497400995f6440ef543c99d&size=tiny"/>
<group name="Burn Notice" href="/data/data.xml?id=netflix-645b8cbeb2754f5cb77696298fff5e13" type="folder" childs="0" art="/images/poster.jpg?id=netflix-645b8cbeb2754f5cb77696298fff5e13&size=tiny"/>
<group name="The Road to El Dorado" href="/data/data.xml?id=netflix-c5a76a26075d40408485fa9c2ca0d72b" type="video" art="/images/poster.jpg?id=netflix-c5a76a26075d40408485fa9c2ca0d72b&size=tiny"/>
<group name="The Running Man" href="/data/data.xml?id=netflix-d19265cad13b498ea94a7f9e1b3d145c" type="video" art="/images/poster.jpg?id=netflix-d19265cad13b498ea94a7f9e1b3d145c&size=tiny"/>
</group>

Netflix/Taylor/MyList/Breaking Bad

<group name="Breaking Bad" href="/data/data.xml?id=netflix-26775c743497400995f6440ef543c99d" type="folder" art="/images/poster.jpg?id=netflix-26775c743497400995f6440ef543c99d&size=tiny">
<group name="Season 1" href="/data/data.xml?id=netflix-a5b3b4541e764a3c839638ee6f374e1e" type="folder" childs="0" art="/images/poster.jpg?id=netflix-a5b3b4541e764a3c839638ee6f374e1e&size=tiny"/>
<group name="Season 2" href="/data/data.xml?id=netflix-0116f794675b4e2180aa182e22d4d7d0" type="folder" childs="0" art="/images/poster.jpg?id=netflix-a5b3b4541e764a3c839638ee6f374e1e&size=tiny"/>
<group name="Season 3" href="/data/data.xml?id=netflix-5789d013866b452a858dcc3321f13b5f" type="folder" childs="0" art="/images/poster.jpg?id=netflix-a5b3b4541e764a3c839638ee6f374e1e&size=tiny"/>
<group name="Season 4" href="/data/data.xml?id=netflix-fb480873895548e08f1bcd0e8e6275ce" type="folder" childs="0" art="/images/poster.jpg?id=netflix-a5b3b4541e764a3c839638ee6f374e1e&size=tiny"/>
<group name="Season 5" href="/data/data.xml?id=netflix-65d155a01fd244869fcda5728c7683ad" type="folder" childs="0" art="/images/poster.jpg?id=netflix-a5b3b4541e764a3c839638ee6f374e1e&size=tiny"/>
</group>

问题是在它到达第 5 季并进入下一个电视节目后,我从 Netflix/Taylor/Mylist 中丢失了文件夹树。下一个文件夹树将以节目名称开头,并丢失之前的任何内容。

 private static void addfolder(string url, string parentFolder, string foldertree)
        {
            string baseurl = null;
            string lastFolder;
            string path = string.Empty;
            string tree = "";

            var xdoc = new XmlDocument();
            xdoc.Load(url);
            // xdoc.Save(Console.Out);


            var playonList = new List<Playon>();


            foreach (XmlNode groups in xdoc.DocumentElement)
            {
                if (groups.Attributes[2].Value == "folder")
                {
                    baseurl = "http://localhost:54479";
                    var netflix = "netflix\\";

                    path = path + "\\" + groups.Attributes[0].Value.Replace(":", "-");
                    playonList.Add(new Playon(groups.Attributes[1].Value, groups.Attributes[0].Value,
                        groups.Attributes[2].Value));
                    lastFolder = groups.Attributes[0].Value;
                    Directory.CreateDirectory("C:\\streamertest\\" + path.Replace(":", "-"));
                    if (File.Exists("C:\\streamertest\\" + path.Replace(":", "-") + "\\data.xml"))
                        xdoc.Save("C:\\streamertest\\" + path.Replace(":", "-") + "\\data" + groups.Attributes[0] +
                                  ".xml");
                    else
                    {
                        xdoc?.Save("C:\\streamertest\\" + path.Replace(":", "-") + "\\data.xml");
                    }

                    Console.WriteLine(groups.Attributes[0].Value);

                   addfolder(baseurl + groups.Attributes[1].Value, lastFolder, path.Replace(":","-"));

                }
            }

【问题讨论】:

  • 缺少“去编写可以做到这一点的递归函数”您面临的实际具体问题是什么?
  • @AlexeiLevenkov 我遇到的主要问题是我设置的文件夹树变量不断重置,没有明显的模式。如果您查看上面的列表,我的函数将创建这些文件夹:最近添加、最近添加/black road、black road、最近添加/black road/bon bin holland、bon bini holland 等。我最近将我的函数重写为尝试使用列表,我不相信这个甚至接近工作...我试图找到一个几乎可以工作的,所以我可以在这里粘贴代码。
  • 请查看minimal reproducible example 指导和edit 问题之一。当前代码没有提供任何信息,为什么 foldertree 可能会发生变化(它甚至没有在任何地方使用)。
  • @AlexeiLevenkov 对不起,我的意思是路径。我纠正了它

标签: c# xml recursion


【解决方案1】:

我假设 xml 文件的开头与您之前发布的一样。 xml 标识是第一行,文件夹元素是第二行。我已经编写递归方法 40 年了,所以这真的很简单。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        const string BASE_URL = "http://localhost:54479";
        static void Main(string[] args)
        {
            string url = "/data/data.xml?id=netflix";
            string directory = "C:\\streamertest";
            string path = "Netflix";
            addfolder(path, url, directory, 0);
            Console.ReadLine();
        }
        public static void addfolder(string path, string url, string directory, int level)
        {

            Console.WriteLine("{0} folder : '{1}'", new string('.', 5 * level), path);

            //Directory.CreateDirectory(directory);

            XDocument xdoc = XDocument.Load(BASE_URL + url);
            XElement root = (XElement)xdoc.FirstNode;

            foreach (XElement element in root.Elements())
            {
                string type = (string)element.Attribute("type");
                string name = (string)element.Attribute("name");
                string href = (string)element.Attribute("href");
                switch (type)
                {
                    case "folder":
                        string newpath = path + "/" + name;
                        string newDirectory = directory + "\\" + name;
                        addfolder(newpath, href, newDirectory, level++);

                        break;
                    default:
                        string pathName = path + "/" + name;

                        Console.WriteLine("{0}   url : '{1}'", new string(' ', 5 * level), pathName);
                        break;
                }

            }
        }
    }

}

【讨论】:

  • 我绝对喜欢你做得更好的方式,但我不确定我将如何获得文件夹树。困难在于,当电视节目切换时,我不知道如何将文件夹树保持在一起。我当前的“路径”变量执行此操作,其中每个管道 |是一个新的 console.writeline。 Netflix | Netflix\名称 | netflix\名称\最近添加 | netflix\名称\最近添加的\电视节目 | netflix\名称\最近添加的\电视节目\第 1 季 |下一个电视节目 | NEXT TV SHOW\Season 1. 当节目改变时,它失去了原来的 netflix\name\category。
  • 从您提供的输入中,我看不到任何树结构。你的 xml 只显示一层,所以我不能假设任何事情。这就是我删除递归的原因。如果您提供了多层 xml,我可以更好地查看是否需要递归。
  • 我将添加第二个文件,但我必须使用不同的类别。你看到 href 属性了吗?每一个都是另一个 xml 文件。它是 netflix,因此,这些 href 中的每一个都是另一层。单击 netflix 上的...“电视节目”,它将加载另一个 xml 图层,显示电视节目类型,然后是每个类型的节目列表,然后是季节列表等。每个新图层都需要我使用 localhost:port/hrefAttributeValue 加载一个新的 xdocument。
  • 我添加了足够的 xml 文件来观看一场演出。当上一季播出时,文件夹树被破坏并从电视节目重新开始,而不是将 netflix/taylor/mylist 保留在它前面。所以在坏掉之后的那个列表中......它应该是..netflix/taylor/my list/burn notice/season1 但它只是burn notice/season 1
  • 我对 xml 文件有点猜测。你发布的文章并没有告诉我真正的结构。我更新了代码。
猜你喜欢
  • 1970-01-01
  • 2011-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多