2012-03-02 65 views
4

我正在使用Tridion核心服务(Tridion 2011 SP1)来检索给定类别ID的关键字列表。Tridion核心服务 - 使用分层分类法

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

这返回什么似乎是一个扁平的XML结构,代表我们的深度为4级的分类。

文档细节的做法与此工作:

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

正如你看到它被称为上公布,但你可以缩小它的一个或多个类别。它会回报你,你可以这样进一步处理吓人XML列表:

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

结果你会得到你的关键字的无序列表和相应的父母说,只要你喜欢,你可以进一步处理。没有父项的项目显然是父项关键字。它可能不是最美丽的解决方案,但至少你只需要一次调用服务器而不读取每个关键字。

1

您可以逐级处理每个分支。下面是一些代码,我一直在与玩弄这是否:

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

我在处理一个平面列表过去发现的层级(在我的情况下,所有SG的名单中公布)与一次处理分支相比,造成了巨大的开销。当然,我应该告诫说,我用Tridion的旧版本(早期的5.x版本)尝试过,所以事情可能从那时起有所改进。

+0

您的算法还会将相关关键字标记为子关键字。您应该使用ChildKeywordsFilterData而不是UsingItemsFilterData。你如何处理具有多个父母的关键字? – 2012-03-02 10:47:15

1

Tridion 2011 SP1带有一个新的CoreService EndPoint。 CoreService 2011.其推荐使用最新的端点。最新的端点有新的功能主义者也修正了错误。 SP1还有一个默认的coreservice客户端代理,您可以直接在您的代码中使用。