簡體   English   中英

Xml簡化/提取不同的值-可能的LINQ

[英]Xml simplification/extraction of distinct values - possible LINQ

對不起,這篇漫長的帖子。...但是我對此任務感到頭疼。

我有一個一英里長的xml文檔,需要在其中提取列表,使用不同的值並傳遞給Web。

我已經使用xslt和keys完成了任務,但是努力迫使服務器屈服了。

說明:xml中的數百種產品,所有產品都有許多命名和ID分類,所有類別至少具有一個帶有名稱和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-效果很好,但性能不佳
  2. 玩過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(); 

    結果是“僅類別”(類別或子類別的不同值)

對它應用了相同的xlst,並獲得了較好的性能.....但仍遠非可用...

我可以在linq語句中應用某種魔術來獲得所需的輸出嗎?

一卡車好業力可以使我指出正確的方向。

// Steen

注意:

  • 如果有人有更好的選擇,我不會堅持使用linq / XDocument
  • 當前在.net 3.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();

問候。

如果我從根本上理解了您的問題,那么這是一個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;
    }));

這會將您的xml解析為具有所有不同子類別名稱的類別字典。 它使用以下庫中的XPath: https//github.com/ChuckSavage/XmlLib/

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。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM