如何获取没有子元素的元素?

时间:2017-05-01 20:14:37

标签: c# xml linq linq-to-xml

这是我的xml:

<Root>  
<FirstChild id="1" att="a">
    <SecondChild id="11" att="aa">
        <ThirdChild>123</ThirdChild>
        <ThirdChild>456</ThirdChild>
        <ThirdChild>789</ThirdChild>
    </SecondChild>
    <SecondChild id="12" att="ab">12</SecondChild>
    <SecondChild id="13" att="ac">13</SecondChild>
</FirstChild>  
<FirstChild id="2" att="b">2</FirstChild>  
<FirstChild id="3" att="c">3</FirstChild>
</Root>

此xml文档非常大,可能是1 GB或更大。为了在查询中获得更好的性能,我想逐步阅读xml doc。因此,在第一步中,我只想阅读&#34; First Child&#34; s及其属性,如下所示:

<FirstChild id="1" att="a"></FirstChild>  
<FirstChild id="2" att="b">2</FirstChild>  
<FirstChild id="3" att="c">3</FirstChild>

在那之后,我可能希望通过他们的父母的身份获得&#34; SecondChild&#34; s ...

<SecondChild id="11" att="aa"></SecondChild>
<SecondChild id="12" att="ab">12</SecondChild>
<SecondChild id="13" att="ac">13</SecondChild>

我该怎么做?

注意:XDoc.Descendants()或XDoc.Elements()加载所有子元素的所有特定元素!

2 个答案:

答案 0 :(得分:1)

如果您有可用于保存文件的内存,我建议将每个搜索步骤视为PLINQ管道外部集合中的项目。

我将从您要检索的节点集合的XName集合开始。通过在XElement构造函数中嵌套查询,您可以返回目标节点的新实例,仅包含名称和属性信息。

使用.Where(...)语句,您还可以过滤保留的属性,允许保留某些子节点等。

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

namespace LinqToXmlExample
{
    public class Program
    {
        public static void Main(string[] args)
        {
            XElement root = XElement.Load("[your file path here]");

            XName[] names = new XName[] { "firstChild", "secondChild", "thirdChild" };

            IEnumerable<XElement> elements =
                names.AsParallel()
                     .Select(
                         name =>
                             new XElement(
                                 $"result_{name}",
                                 root.Descendants(name)
                                     .AsParallel()
                                     .Select(
                                        x => new XElement(name, x.Attributes()))))
                     .ToArray();
        }
    }
}

答案 1 :(得分:0)

在VB中你可以这样做以获得FirstChild的列表

    'Dim yourpath As String = "your path here"
    Dim xe As XElement
    'to load from a file
    'xe = XElement.Load(yourpath)

    'for testing
    xe = <Root>
             <FirstChild id="1" att="a">
                 <SecondChild id="11" att="aa">
                     <ThirdChild>123</ThirdChild>
                     <ThirdChild>456</ThirdChild>
                     <ThirdChild>789</ThirdChild>
                 </SecondChild>
                 <SecondChild id="12" att="ab">12</SecondChild>
                 <SecondChild id="13" att="ac">13</SecondChild>
             </FirstChild>
             <FirstChild id="2" att="b">2</FirstChild>
             <FirstChild id="3" att="c">3</FirstChild>
         </Root>

    Dim ie As IEnumerable(Of XElement)
    ie = xe...<FirstChild>.Select(Function(el)
                                      'create a copy
                                      Dim foo As New XElement(el)
                                      foo.RemoveNodes()
                                      Return foo
                                  End Function)