English 中文(简体)
Xml 不同值的简化/解析 - 可能的 LINQ
原标题:Xml simplification/extraction of distinct values - possible LINQ

很遗憾这长篇留言... 但我头痛

我有一英里长的xml文件 我需要提取一个列表, 使用不同的值, 并传递到网络转换。

我用 xslt 和 键完成了任务, 但努力迫使服务器屈膝 。

Description: hundreds of products in xml, all with a number of named and Id ed cattegories, all categories with at least one subcategory with name and id.

类别与 ID 不同, 所有子类别都与该类别不同:

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

<?xml version="1.0" encoding="utf-8"?>
<root>
<productlist>
<product id="1">
<name>Some Product</name>
<categorylist>
<category id="1">
<name>cat1</name>
<subcategories>
<subcat id="1">
<name>subcat1</name>
</subcat>
<subcat id="2">
<name>subcat1</name>
</subcat>
</subcategories>
</category>
<category id="2">
<name>cat1</name>
<subcategories>
<subcat id="1">
<name>subcat1</name>
</subcat>
</subcategories>
</category>
<category id="3">
<name>cat1</name>
<subcategories>
<subcat id="1">
<name>subcat1</name>
</subcat>
</subcategories>
</category>
</categorylist>
</product>
<product id="2">
<name>Some Product</name>
<categorylist>
<category id="1">
<name>cat1</name>
<subcategories>
<subcat id="2">
<name>subcat2</name>
</subcat>
<subcat id="4">
<name>subcat4</name>
</subcat>
</subcategories>
</category>
<category id="2">
<name>cat2</name>
<subcategories>
<subcat id="1">
<name>subcat1</name>
</subcat>
</subcategories>
</category>
<category id="3">
<name>cat3</name>
<subcategories>
<subcat id="1">
<name>subcat1</name>
</subcat>
</subcategories>
</category>
</categorylist>
</product>
</productlist>
</root>

<强度 > 发展结果:

<?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>

(2000年产品将产生10类产品,5至15个子类)

尝试过的事情:

  1. Xslt with keys - works fine, but pooooor performance
  2. 与林克玩耍:

           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();
    

    结果是“只有类别”(没有类别或亚类的不同值)

将同样的xLst应用到这个上面, 并取得了相当好的性能... 但仍然远远不能使用...

我可以运用某种魔法 与林格语句 获得想要的输出吗?

一卡车好货 运到那些可以指向我 向正确方向的人...

// 17个

注:

  • I am not stuck on using linq/XDocument if anyone has better options
  • Currently on .net 3.5, can switch to 4 if needed
最佳回答

如果我从核心上理解你的问题,这里就是LINQ的企图。

下面的查询剖析您的 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;
    }));
问题回答

尝试一下我为它做了一些事情。 缺少属性。 您可以使用 XE元素 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();

请注意

这将将您的 xml 解析成包含所有不同子类名称的分类词典。 它使用来自此库的 XPath : < a href="https://github.com/ ChuckSavage/XmlLib/" rel="no follow" >https://github.com/ ChuckSavage/XmLib/

XElement root = XElement.Load(file);
string[] cats = root.XGet("//category/name", string.Empty).Distinct().ToArray();
Dictionary<string, string[]> dict = new Dictionary<string, string[]>();
foreach (string cat in cats)
{
    // Get all the categories by name and their subcat names
    string[] subs = root
        .XGet("//category[name={0}]/subcategories/subcat/name", string.Empty, cat)
        .Distinct().ToArray();
    dict.Add(cat, subs);
}

或用一个句子来解释:

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());

我给你一个任务,从字典上 组装你产生的xml。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Transaction handling with TransactionScope

I am implementing Transaction using TransactionScope with the help this MSDN article http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx I just want to confirm that is ...

System.Web.Mvc.Controller Initialize

i have the following base controller... public class BaseController : Controller { protected override void Initialize(System.Web.Routing.RequestContext requestContext) { if (...

Microsoft.Contracts namespace

For what it is necessary Microsoft.Contracts namespace in asp.net? I mean, in what cases I could write using Microsoft.Contracts;?

Separator line in ASP.NET

I d like to add a simple separator line in an aspx web form. Does anyone know how? It sounds easy enough, but still I can t manage to find how to do it.. 10x!

热门标签