C# Xml简化/提取不同值-可能的LINQ

C# Xml简化/提取不同值-可能的LINQ,c#,asp.net,xml,linq,C#,Asp.net,Xml,Linq,很抱歉发了这么长的帖子……但是我因为这个任务而头疼 我有一个一英里长的xml文档,我需要在其中提取一个列表,使用不同的值,并将转换传递到web 我已经使用xslt和keys完成了任务,但这项工作正在迫使服务器屈服 说明: xml格式的数百种产品,都有许多命名和Id的cattegories,所有类别都至少有一个子类别具有name和Id 类别是唯一的ID,该类别中的所有子类别都是唯一的: 巨大文件中的简化示例(留下大量与任务无关的信息): 一些产品 第一类 子目录1 子目录1 第一类 子目录1 第

很抱歉发了这么长的帖子……但是我因为这个任务而头疼

我有一个一英里长的xml文档,我需要在其中提取一个列表,使用不同的值,并将转换传递到web

我已经使用xslt和keys完成了任务,但这项工作正在迫使服务器屈服

说明: xml格式的数百种产品,都有许多命名和Id的cattegories,所有类别都至少有一个子类别具有name和Id

类别是唯一的ID,该类别中的所有子类别都是唯一的:

巨大文件中的简化示例(留下大量与任务无关的信息):


一些产品
第一类
子目录1
子目录1
第一类
子目录1
第一类
子目录1
一些产品
第一类
副2
子类别4
第二类
子目录1
第三类
子目录1
所需结果:

<?xml version="1.0" encoding="utf-8"?>
<root>
<maincat id="1">
<name>cat1</name>
<subcat id="1"><name>subcat1</name></subcat>
<subcat id="2"><name>subcat2</name></subcat>
<subcat id="3"><name>subcat3</name></subcat>
</maincat>
<maincat id="2">
<name>cat2</name>
<subcat id="1"><name>differentsubcat1</name></subcat>
<subcat id="2"><name>differentsubcat2</name></subcat>
<subcat id="3"><name>differentsubcat3</name></subcat>
</maincat>
<maincat id="2">
<name>cat2</name>
<subcat id="1"><name>differentsubcat1</name></subcat>
<subcat id="2"><name>differentsubcat2</name></subcat>
<subcat id="3"><name>differentsubcat3</name></subcat>
</maincat>
</root>

第一类
子目录1
副2
次级T3
第二类
差分卡1
差分卡2
差分卡3
第二类
差分卡1
差分卡2
差分卡3
(2000年的原始产品将产生10个类别,包括5到15个子类别)

尝试过的事情:

  • 带键的Xslt—工作正常,但性能不佳
  • 与linq一起玩:

           IEnumerable<XElement> mainCats =
                    from Category1 in doc.Descendants("product").Descendants("category") select Category1;
    
                var cDoc = new XDocument(new XDeclaration("1.0", "utf-8", null), new XElement("root"));
                cDoc.Root.Add(mainCats);
                cachedCategoryDoc = cDoc.ToString();
    
    IEnumerable mainCats=
    从文档子体(“产品”)中的类别1。子体(“类别”)选择类别1;
    var cDoc=新XDocument(新XDeclaration(“1.0”、“utf-8”、null)、新XElement(“根”);
    cDoc.Root.Add(mainCats);
    cachedCategoryDoc=cDoc.ToString();
    
    结果是“仅类别”(不是类别或子类别的不同值)

  • 将相同的xlst应用于此,并获得了相当好的性能。。。。。但仍然远远不能使用

    我可以对linq语句应用某种魔法来获得所需的输出吗

    一卡车的好业力流向那些能给我指明正确方向的人

    //斯汀

    注:

    • 如果有更好的选择,我不会坚持使用linq/XDocument
    • 目前在.NET3.5上,如果需要,可以切换到4

      • 试试看,我已经为此做了些什么。。缺少属性。您可以使用XElement ctor添加属性

         var doc = XDocument.Load(reader);
                            IEnumerable<XElement> mainCats =
                                doc.Descendants("product").Descendants("category").Select(r =>
                                    new XElement("maincat", new XElement("name", r.Element("name").Value),
                                        r.Descendants("subcat").Select(s => new XElement("subcat", new XElement("name", s.Element("name").Value)))));
        
        
                            var cDoc = new XDocument(new XDeclaration("1.0", "utf-8", null), new XElement("root"));
                            cDoc.Root.Add(mainCats);
                            var cachedCategoryDoc = cDoc.ToString();
        
        var doc=XDocument.Load(读卡器);
        数不清的猫=
        文档子体(“产品”)。子体(“类别”)。选择(r=>
        新元素(“maincat”、新元素(“名称”、r元素(“名称”)。值),
        r、 子体(“子集合”)。选择(s=>new-XElement(“子集合”),new-XElement(“名称”,s.Element(“名称”).Valueщщ);
        var cDoc=新XDocument(新XDeclaration(“1.0”、“utf-8”、null)、新XElement(“根”);
        cDoc.Root.Add(mainCats);
        var cachedCategoryDoc=cDoc.ToString();
        

        问候。

        试试这个,我已经为此做了些什么。。缺少属性。您可以使用XElement ctor添加属性

         var doc = XDocument.Load(reader);
                            IEnumerable<XElement> mainCats =
                                doc.Descendants("product").Descendants("category").Select(r =>
                                    new XElement("maincat", new XElement("name", r.Element("name").Value),
                                        r.Descendants("subcat").Select(s => new XElement("subcat", new XElement("name", s.Element("name").Value)))));
        
        
                            var cDoc = new XDocument(new XDeclaration("1.0", "utf-8", null), new XElement("root"));
                            cDoc.Root.Add(mainCats);
                            var cachedCategoryDoc = cDoc.ToString();
        
        var doc=XDocument.Load(读卡器);
        数不清的猫=
        文档子体(“产品”)。子体(“类别”)。选择(r=>
        新元素(“maincat”、新元素(“名称”、r元素(“名称”)。值),
        r、 子体(“子集合”)。选择(s=>new-XElement(“子集合”),new-XElement(“名称”,s.Element(“名称”).Valueщщ);
        var cDoc=新XDocument(新XDeclaration(“1.0”、“utf-8”、null)、新XElement(“根”);
        cDoc.Root.Add(mainCats);
        var cachedCategoryDoc=cDoc.ToString();
        

        问候。

        如果我正确理解了你的问题,这里有一个关键提示

        下面的查询解析XML数据并创建一个自定义类型,该类型表示一个类别并包含该元素的子类别

        解析后,数据按类别Id分组,以获得每个类别的不同子类别

        var doc = XElement.Load("path to the file");
        var results = doc.Descendants("category")
            .Select(cat => new
            {
                Id = cat.Attribute("id").Value,
                Name = cat.Descendants("name").First().Value,
                Subcategories = cat.Descendants("subcat")
                    .Select(subcat => new
                    {
                        Id = subcat.Attribute("id").Value,
                        Name = subcat.Descendants("name").First().Value
                    })
             })
             .GroupBy(x=>x.Id)
             .Select(g=>new
             {
                 Id = g.Key,
                 Name = g.First().Name,
                 Subcategories = g.SelectMany(x=>x.Subcategories).Distinct()
             });
        
        根据以上结果,您可以使用以下代码创建文档:

        var cdoc = new XDocument(new XDeclaration("1.0", "utf-8", null), new XElement("root")); 
        cdoc.Root.Add(
            results.Select(x=>
            {
                var element = new XElement("maincat", new XAttribute("id", x.Id));
                element.Add(new XElement("name", x.Name));
                element.Add(x.Subcategories.Select(c=>
                {
                    var subcat = new XElement("subcat", new XAttribute("id", c.Id));
                    subcat.Add(new XElement("name", c.Name));
                    return subcat;
                }).ToArray());
                return element;
            }));
        

        如果我正确理解了你的问题,这里有一个关键的提示

        下面的查询解析XML数据并创建一个自定义类型,该类型表示一个类别并包含该元素的子类别

        解析后,数据按类别Id分组,以获得每个类别的不同子类别

        var doc = XElement.Load("path to the file");
        var results = doc.Descendants("category")
            .Select(cat => new
            {
                Id = cat.Attribute("id").Value,
                Name = cat.Descendants("name").First().Value,
                Subcategories = cat.Descendants("subcat")
                    .Select(subcat => new
                    {
                        Id = subcat.Attribute("id").Value,
                        Name = subcat.Descendants("name").First().Value
                    })
             })
             .GroupBy(x=>x.Id)
             .Select(g=>new
             {
                 Id = g.Key,
                 Name = g.First().Name,
                 Subcategories = g.SelectMany(x=>x.Subcategories).Distinct()
             });
        
        根据以上结果,您可以使用以下代码创建文档:

        var cdoc = new XDocument(new XDeclaration("1.0", "utf-8", null), new XElement("root")); 
        cdoc.Root.Add(
            results.Select(x=>
            {
                var element = new XElement("maincat", new XAttribute("id", x.Id));
                element.Add(new XElement("name", x.Name));
                element.Add(x.Subcategories.Select(c=>
                {
                    var subcat = new XElement("subcat", new XAttribute("id", c.Id));
                    subcat.Add(new XElement("name", c.Name));
                    return subcat;
                }).ToArray());
                return element;
            }));
        

        这将把xml解析成一个包含所有不同子类别名称的类别字典。它使用此库中的XPath:

        XElement root=XElement.Load(文件);
        string[]cats=root.XGet(“//category/name”,string.Empty).Distinct().ToArray();
        Dictionary dict=新字典();
        foreach(猫中的串猫)
        {
        //按名称及其子类别名称获取所有类别
        字符串[]subs=根
        .XGet(“//category[name={0}]/subcategories/subcat/name”,string.Empty,cat)
        .Distinct().ToArray();
        dict.Add(目录、子目录);
        }
        
        或将解析作为一条语句:

        Dictionary<string, string[]> dict = root
            .XGet("//category/name", string.Empty)
            .Distinct()
            .ToDictionary(cat => cat, cat => root
                .XGet("//category[name={0}]/subcategories/subcat/name", string.Empty, cat)
                .Distinct().ToArray());
        
        Dictionary dict=root
        .XGet(“//类别/名称”,string.Empty)
        .Distinct()
        .ToDictionary(cat=>cat,cat=>root
        .XGet(“//category[name={0}]/subcategories/subcat/name”,string.Empty,cat)
        .Distinct().ToArray());
        

        我给您的任务是从字典中汇编生成的xml。

        这将把xml解析成一个包含所有不同子类别名称的类别字典。它使用此库中的XPath:

        XElement root=XElement.Load(文件);
        string[]cats=root.XGet(“//category/name”,string.Empty).Distinct().ToArray();
        Dictionary dict=新字典();
        foreach(猫中的串猫)
        {
        //按名称及其子类别名称获取所有类别
        字符串[]subs=根
        .XGet(“//category[name={0}]/subcategories/subcat/name”,string.Empty,cat)
        .Distinct().ToArray();
        dict.Add(目录、子目录);
        }
        
        还是pa