0

この長い投稿で申し訳ありません....しかし、私はこの仕事から頭痛がしています。

リストを抽出し、個別の値を使用し、変換のために Web に渡す必要がある 1 マイルの xml ドキュメントがあります。

xslt とキーを使用してタスクを完了しましたが、その努力によってサーバーはひざまずきます。

説明: xml 内の数百の製品。すべてに名前と ID が付けられた多数のカテゴリがあり、すべてのカテゴリには名前と ID を持つ少なくとも 1 つのサブカテゴリがあります。

カテゴリは 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 年の製品からの当初の意志では、5 から 15 のサブカテゴリを持つ 10 のカテゴリが生成されます)

試したこと:

  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 ステートメントである種の魔法を適用できますか??

良いカルマのトラックは、私を正しい方向に向けることができるものに行きます..

//スティーン

ノート:

  • 誰かがより良いオプションを持っている場合、私はlinq/XDocumentの使用に固執していません
  • 現在 .net 3.5 を使用していますが、必要に応じて 4 に切り替えることができます
4

3 に答える 3

1

これにより、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);
}

または、1 つのステートメントとしての解析:

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 をディクショナリから組み立てる作業を行います。

于 2012-06-05T11:26:54.367 に答える
1

これを試してください。私はそれのために何かをしました..属性がありません.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();

よろしく。

于 2012-05-25T12:40:41.617 に答える
1

私があなたの質問を正しく理解していれば、ここに 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;
    }));
于 2012-05-25T12:42:58.183 に答える