首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将XmlNodeList拆分为两个子XmlNodeList?

如何将XmlNodeList拆分为两个子XmlNodeList?
EN

Stack Overflow用户
提问于 2018-05-08 21:53:14
回答 2查看 278关注 0票数 0

我如何将一个XmlNodeList分解成两个较小的XmlNodeList,其中一个具有大小N,而另一个有大小总计- N?

参见下面的一个例子,以及我试图这样做的地方:

代码语言:javascript
复制
    public static void Main(string[] args)
    {
        XmlDocument someDoc = new XmlDocument();
        someDoc.LoadXml(@"<bananas>
                            <banana tasty='yes'></banana>
                            <banana tasty='very'></banana>
                            <banana tasty='amazing'></banana>
                            <banana tasty='mind-blowing'></banana>
                            <banana tasty='disgusting'></banana>
                          </bananas>");
        XmlNodeList bananaNodeList = someDoc.SelectNodes("//banana");
        eatSomeBananas(bananaNodeList, 2);
    }

    /** Splits a XmlNodeList into two XmlNodeList, first one is a slice from 0 to numberOfBananas-1, and the other slice is from numberOfBananas and onwards
    */
    public static void eatSomeBananas(XmlNodeList subBananaNodeList, int numberOfBananas)
    {
        XmlNodeList bananasToEat = subBananaNodeList.Cast<XmlNode>().Take(numberOfBananas) as XmlNodeList; //Error down-casting - null!
        if (bananasToEat == null)
            Console.WriteLine("Error! Did not work");
        /*else 
            doSomethingHere(bananasToEat); */
        XmlNodeList remainingBananas = subBananaNodeList.Cast<XmlNode>().Skip(numberOfBananas) as XmlNodeList; //Error down-casting - null!
        eatSomeBananas(remainingBananas, numberOfBananas);
    }

我试图将XmlNodeList转换为IEnumerable<XmlNode> (因为前者继承了后者)--我认为这应该是向上的。之后,我不应该把它降回XmlNodeList吗?但如果没有,为什么不呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-08 22:30:34

之后,我不应该把它降回XmlNodeList吗?但如果没有,为什么不呢?

不,因为从Skip返回的值不是XmlNodeList。它只被声明为IEnumerable<XmlNode>,我希望Skip实现可能使用迭代器块.当然,如果SkipXmlNodeList有任何详细的了解,我会感到惊讶的。Take将以完全相同的方式工作。

就我个人而言,我完全避免使用旧的XML,而只是使用LINQ。这对LINQ来说很自然--而且通常是一个更好的XML,IMO。

您不必使用这个,请注意-您可以将整个代码更改为使用IEnumerable<XmlNode>而不是XmlNodeList

代码语言:javascript
复制
public static void eatSomeBananas(IEnumerable<XmlNode> subBananaNodeList, int numberOfBananas)
{
    IEnumerable<XmlNode> bananasToEat = subBananaNodeList.Take(numberOfBananas);
    IEnumerable<XmlNode> remainingBananas = subBananaNodeList.Skip(numberOfBananas);
    // Added condition to avoid infinite recursion
    if (remainingBananas.Any())
    {
        eatSomeBananas(remainingBananas, numberOfBananas);
    }
}

然后,在调用该方法时,只需调用一次Cast

代码语言:javascript
复制
eatSomeBananas(bananaNodeList.Cast<XmlNode>(), 2);

下面是LINQ版本,我更喜欢这个版本:

代码语言:javascript
复制
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

public class Test
{
    public static void Main(string[] args)
    {
        XDocument someDoc = XDocument.Parse(
            @"<bananas>
                <banana tasty='yes'></banana>
                <banana tasty='very'></banana>
                <banana tasty='amazing'></banana>
                <banana tasty='mind-blowing'></banana>
                <banana tasty='disgusting'></banana>
              </bananas>");
        IEnumerable<XElement> bananas = someDoc.Descendants("banana");
        EatSomeBananas(bananas, 2);
    }

    public static void EatSomeBananas(IEnumerable<XElement> bananas, int numberOfBananas)
    {
        var bananasToEat = bananas.Take(numberOfBananas);
        Console.WriteLine("Eating some bananas"); 
        foreach (var element in bananasToEat)
        {
            var tasty = element.Attribute("tasty").Value;
            Console.WriteLine($"Tasty: {tasty}");
        }
        Console.WriteLine("Eaten the bananas");
        var remainingBananas = bananas.Skip(numberOfBananas);
        if (remainingBananas.Any())
        {
            EatSomeBananas(remainingBananas, numberOfBananas);
        }
    }
}

请注意,对于生产实现,我会避免递归,并可能周期性地实现结果-否则每次都会迭代,跳过一个负载,然后取一些。

票数 2
EN

Stack Overflow用户

发布于 2018-05-08 22:14:36

我只是转换成一个IQueryable并使用它,比使用XmlNodeList容易得多。

代码语言:javascript
复制
    public static void Main(string[] args)
    {
        XmlDocument someDoc = new XmlDocument();
        someDoc.LoadXml(@"<bananas>
                        <banana tasty='yes'></banana>
                        <banana tasty='very'></banana>
                        <banana tasty='amazing'></banana>
                        <banana tasty='mind-blowing'></banana>
                        <banana tasty='disgusting'></banana>
                      </bananas>");
        XmlNodeList bananaNodeList = someDoc.SelectNodes("//banana");

        var allBananas = bananaNodeList.Cast<XmlNode>().AsQueryable();

        eatSomeBananas(allBananas, 2);
    }

    public static void eatSomeBananas(IQueryable<XmlNode> subBananas, int numberOfBananas)
    {
        var bananasToEat = subBananas.Take(numberOfBananas);
        var remainingBananas = subBananas.Skip(numberOfBananas);

        Console.WriteLine(string.Format("Bananas to eat: {0}", bananasToEat.Count()));
        Console.WriteLine(string.Format("Remaining bananas: {0}", remainingBananas.Count()));
        if (!bananasToEat.Any())
            Console.WriteLine("Error! Did not work (not enough bananas!)");
        else 
            eatSomeBananas(remainingBananas, numberOfBananas);
    }

输出:

代码语言:javascript
复制
Bananas to eat: 2
Remaining bananas: 3
Bananas to eat: 2
Remaining bananas: 1
Bananas to eat: 1
Remaining bananas: 0
Bananas to eat: 0
Remaining bananas: 0
Error! Did not work (not enough bananas!)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50242774

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档