2012-03-02 19 views
4

Tridion Core Service(Tridion 2011 SP1)を使用して、特定のカテゴリIDのキーワードリストを取得しています。Tridion Coreサービス - 階層分類を使用して作業する

CoreService2010Client client = new CoreService2010Client(); 
XElement xmlCategoryKeywords = client.GetListXml(category.Id, 
               new KeywordsFilterData()); 

これは、4レベルの深さである私たちのタクソノミーを表すフラットなXML構造であると思われるものを返します。

ドキュメントでは、これを操作するためのアプローチを詳細:

var categoryKeywords = xmlCategoryKeywords.Elements().Select(element => 
    element.Attribute("ID").Value).Select(id => (KeywordData)client.Read(id, null) 
); 
foreach (KeywordData keyword in categoryKeywords) 
{ 
    Console.WriteLine("\t Keyword ID={0}, Title={1}", keyword.Id, keyword.Title); 
} 

しかし、これが唯一の各キーワードの一覧が表示されます。 KeywordDataオブジェクトにはプロパティParentKeywordsが含まれているため、階層をメモリに構築することができます。

コアサービスからXMLを階層構造で取得することは可能ですか?このデータを扱う簡単な方法は?

答えて

4

一つの方法TaxonomiesOwlFilterDataを使用することです:

string publicationId = "tcm:0-3-1"; 
var filter = new TaxonomiesOwlFilterData(); 
filter.RootCategories = new[] {new LinkToCategoryData{ IdRef = "tcm:3-158-512"},}; 
var list = ClientAdmin.GetListXml(publicationId, filter); 

あなたはそれが出版物に呼ばれて参照していますが、1つ以上のカテゴリにそれを絞り込むことができたよう。あなたが好きなようにあなたがプロセスを進めることができ、あなたのキーワードの順序なしリストと、対応する親を取得しますその結果

XNamespace tcmc = publicationId + "/Categories#"; 
XNamespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; 
XNamespace tcmt = "http://www.tridion.com/ContentManager/5.2/Taxonomies#"; 

var taxonomyTree = new Dictionary<string, List<string>>(); 
var keywordNodes = list.Descendants(tcmc + "cat"); 
foreach (var keywordNode in keywordNodes) 
{ 
    var parents = new List<string>(); 
    var parentNodes = keywordNode.Descendants(tcmt + "parentKeyword"); 
    if (parentNodes.Count() > 0) 
    { 
     foreach (var parentNode in parentNodes) 
     { 
     parents.Add(parentNode.Attribute(rdf + "resource").Value); 
     } 
    } 
taxonomyTree.Add(keywordNode.Attribute(rdf + "about").Value, parents); 
} 

:それはあなたがこのようにプロセスを進めることができ怖いXMLのリストを返します。親を持たないアイテムは明らかに親キーワードです。それは最も美しい解決策ではないかもしれませんが、少なくともサーバーへの呼び出しは1回で済み、各キーワードを読み取る必要はありません。

1

レベルごとに各ブランチを処理できます。ここで私はそれで遊んでてきたいくつかのコードがないということ:私は(公報に私の場合は、すべてのSGのリストを)における階層にフラットリストの処理を過去に見つけた

CoreService2010Client client = new CoreService2010Client("basicHttp_2010"); 

KeywordsFilterData keywordsDataFilter = new KeywordsFilterData() 
{ 
    BaseColumns = ListBaseColumns.IdAndTitle, 
    IsRoot = true 
}; 

UsingItemsFilterData usingItemsFilter = new UsingItemsFilterData() 
{ 
    BaseColumns = ListBaseColumns.IdAndTitle, 
    ItemTypes = new[] { ItemType.Keyword }, 
    InRepository = new LinkToRepositoryData() { IdRef = "tcm:0-1-1" } 
}; 

XElement parents = client.GetListXml("tcm:1-272-512", keywordsDataFilter); 

foreach (XElement parent in parents.Descendants()) 
{ 
    // Do something with the parent (top level) KW 

    XElement children = client.GetListXml(parent.Attribute("ID").Value, usingItemsFilter); 

    foreach (XElement child in children.Descendants()) 
    { 
     // Do something with the child KW 
    } 
} 

一度にブランチを処理するのに比べて大規模なオーバーヘッドが発生しました。もちろん、古い(初期の5.x)バージョンのTridionで試してみると、それ以降は改良されているかもしれないと言って、注意する必要があります。

+0

あなたのアルゴリズムは、関連キーワードを子キーワードとしてマークします。 UsingItemsFilterDataの代わりにChildKeywordsFilterDataを使用する必要があります。複数の親を持つキーワードをどう扱っていますか? –

1

Tridion 2011 SP1には、新しいCoreService EndPointが付属しています。 CoreService 2011.最新のエンドポイントを使用することをお勧めします。最新のエンドポイントには、新しいファンクショナリズムもあります。 SP1には、コードで直接使用できるデフォルトのcoreserviceクライアントプロキシもあります。

関連する問題