Tridion核心服务 - 使用分层分类法

时间:2012-03-02 08:44:17

标签: tridion

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

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,因此可以在内存中构建层次结构。

是否可以使用分层结构从Core Service检索XML?或者更简单的方法来处理这些数据?

3 个答案:

答案 0 :(得分: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 :(得分: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的列表)与一次处理分支相比产生了巨大的开销。当然,我应该通过说我用旧的(早期的5.x)版本的Tridion来尝试这一点,所以事情可能会有所改善。

答案 2 :(得分:1)

Tridion 2011 SP1附带了一个新的CoreService EndPoint。 CoreService 2011.建议使用最新的端点。最新的端点有新的功能主义者也有bug修复。 SP1还有一个默认的核心服务客户端代理,您可以直接在代码中使用它。