c#LINQ过滤XML,保持树层次结构

时间:2017-04-14 18:35:42

标签: xml

我已经过滤了像IEnumerable

这样的数据
   xDOCfiltered = xDOC
        .Where(k => 
            (
                ( k.Attribute("Object_Heading").Value.Trim() == "Author" && k.Parent.Attribute("Milestones").Value.Contains(milestone) )
                //
                || k.Attribute("Milestones").Value.Contains(milestone)
            ) 

            && filterUID.IsMatch(k.Attribute("Unique_ID").Value.Trim())
            && GetHierarchy(k).First() == "Code"
            )
        ;

现在我发现当我使用

foreach (XElement xobj in xGDMfiltered)
{
...
...
XNode previousNode = xobj.PreviousNode;
...
...

}

我的PREV节点是指原始的xDOC结构,未过滤的一个:( 我不清楚,LINQ返回的xDOCfiltered只是一个简单的列表,所有的层次结构信息都丢失了?

看起来似乎是合乎逻辑的,linq会返回一个集合。

我加载我的结构如下

            x= XDocument.Load(myXml);

            xDOC = x.Element("root").Descendants("record");

我可以以某种方式过滤并仍然保留(重建)层次结构吗? 像删除LINQ表达式过滤的所有节点一样吗?

非常感谢您提前,

PS。 我想到的第一件事是做一个foreach到过滤列表并从x文档中删除那些节点,但有一个更优雅的解决方案?

这需要几分钟,原始未经过滤的doc有> 18.000个节点!

1 个答案:

答案 0 :(得分:0)

如果有人需要这个,我通过首先否定所有子句来修复,然后一次删除所有不匹配的节点。与foreach删除相比,这是非常快的。

            x.Element("root").Descendants("record") // delete if
                .Where(k => 
                    !( // NEGATE so keep this kind of objects

                        // contains desired milestone
                        k.Attribute("Milestones").Value.Contains(milestone)

                        || // or

                        (k.Attribute("Object_Heading").Value.Trim() == "Author" && k.Parent.Attribute("Milestones").Value.Contains(milestone))
                    ) 

                    // or if UID is not in this format
                    || !filterUID.IsMatch(k.Attribute("Unique_ID").Value.Trim()) // and this format for UID

                    // or if first parent (except root) is not a Code  
                    || GetHierarchy(k).First() != "Code"

                    ).Remove()
                ;

                xDOCfiltered =
                    x.Element("root").Descendants("record");