4

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

是否可以从具有层次结构的核心服务中检索 XML?或者更简单的方法来处理这些数据?

4

3 回答 3

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

结果,您将获得关键字和相应父母的无序列表,您可以根据需要进一步处理。没有父项的项显然是父关键字。它可能不是最漂亮的解决方案,但至少您只需要一次调用服务器而不读取每个关键字。

于 2012-03-02T09:37:16.373 回答
1

Tridion 2011 SP1 带有一个新的 CoreService EndPoint。CoreService 2011。建议使用最新的端点。最新的端点有新的功能主义者也修复了错误。SP1 也有一个默认的 coreservice 客户端代理,你可以直接在你的代码中使用它。

于 2012-04-03T17:59:57.063 回答
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,因此从那时起情况可能有所改善。

于 2012-03-02T10:10:43.887 回答