我可以使用FullPath以编程方式逃避Sitecore查询中的破折号吗?

Jam*_*emp 7 sitecore sitecore7

我正在尝试扩展自定义Sitecore命令以确定当前项目是否具有与特定模板ID匹配的父项目.

我知道查询理想情况下应该像./ancestor::*[@@templateid='{26710865-F082-4714-876B-D5E1F386792F}']项目是上下文一样简单,或者/sitecore/content/home/full/path/to/the-item/ancestor::*[@@templateid='{26710865-F082-4714-876B-D5E1F386792F}']

不幸的是,项目路径包括需要像其一样进行转义的破折号/sitecore/content/home/full/path/to/#the-item#/ancestor::*[@@templateid='{26710865-F082-4714-876B-D5E1F386792F}'].

但是,理想情况下我只想使用项目的完整路径,因为它可用item.Paths.FullPath.

给定一个项目,编写包含它的完整路径的查询以及转义可能包含在内的任何破折号的最佳方法是什么?

Mar*_*lak 6

我从未见过任何 Sitecore util 类或任何其他开箱即用的代码可以满足您的需求。有趣的是,Sitecore 确实有一个返回的 util 方法false(是的,它确实 return false)但没有转义项目路径的方法,因此它可以在查询中使用。

你可以在这里找到你想要的代码(由 Anders Laub 编写):https : //blog.istern.dk/2014/10/29/escaping-dashes-in-sitecore-queries-datasource-query-update/

如果你懒得点击链接,我已经复制到这里的代码:

private string EscapeItemNamesWithDashes(string queryPath)
{
  if (!queryPath.Contains("-"))
   return queryPath;

  var strArray = queryPath.Split(new char[] { '/' });
  for (int i = 0; i < strArray.Length; i++)
  {
    if (strArray[i].IndexOf('-') > 0)
    strArray[i] = "#" + strArray[i] + "#";
  }
  return string.Join("/", strArray);
}
Run Code Online (Sandbox Code Playgroud)

如果你也想转义空格字符,你可以试试这个正则表达式:

string escapedPath = Regex.Replace(myItem.Paths.FullPath, "[^/]*[- ][^/]*", "#$0#");
Run Code Online (Sandbox Code Playgroud)

您还应该记住,Sitecore 中有一些保留字也应该被转义。这些是(从http://www.newguid.net/sitecore/2012/escape-characterswords-in-a-sitecore-query/复制):

  • 祖先
  • 孩子
  • 后裔
  • div
  • 错误的
  • 下列的
  • 模组
  • 或者
  • 父母
  • 自己
  • 真的
  • 异或


zzz*_*Bov 5

假设

假设你有一个Sitecore.Data.Items.Item(被叫item)的引用,并且你想找到一个给定Sitecore.Data.ID(被叫id)的祖先,你可以通过多种方式访问​​祖先.

使用Linq

在没有任何自定义库的典型Sitecore设置中,我通常会使用一些Linq以避免XPath中的编码问题.

ancestor =
    item
        .Axes
        .GetAncestors()
        .FirstOrDefault(ancestor => ancestor.TemplateID == id);
Run Code Online (Sandbox Code Playgroud)

运用 Closest

我使用定制的Sitecore开发框架,涉及各种扩展方法和自定义项目生成.为了避免在过滤之前访问所有祖先的开销,我会使用Closest扩展方法:

public static Item Closest(this Item source, Func<Item, bool> test)
{
    Item cur;
    for (cur = source; cur != null; cur = cur.Parent)
    if (test(cur))
        break;
    return cur;
}
Run Code Online (Sandbox Code Playgroud)

访问祖先将是:

ancestor =
    item
        .Closest(ancestor => ancestor.TemplateID == id);
Run Code Online (Sandbox Code Playgroud)

(实际上,我通常使用看起来像的代码)

ancestor = (ITemplateNameItem) item.Closest(Is.Type<ITemplateNameItem>);
Run Code Online (Sandbox Code Playgroud)

使用XPath

我通常避免使用XPath并且仅将其用作最后的工具,因为它经常使代码难以阅读,引入编码问题,例如您在此问题中遇到的问题,并且对项目数量有严格限制可以退货.

也就是说,Sitecore有许多可用于使用XPath进行搜索的工具,在某些情况下它确实简化了操作.

修复包含空格的项目路径的技巧是:不要使用项目路径.

相反,你可以放心地使用商品的ID,没有必要更多的背景,因为它是一个绝对的参考项.它也保证遵循特定的格式.

var query =
    string.Format(
        "//{0}/ancestor::*[@@templateid='{1}']",
        item.ID.ToString(),
        id.ToString());
/* alternatively
var query =
    string.Format(
        "{0}/ancestor::*[@@templateid='{1}']",
        item.Paths.LongID,
        id.ToString());
*/
ancestor =
    item
        .Database
        .SelectSingleItem(query);
Run Code Online (Sandbox Code Playgroud)

运用 Sitecore.Data.Query.Query

正如我之前提到的,Sitecore有许多工具可用于使用XPath进行搜索.其中一个工具是Sitecore.Data.Query.Query.的SelectItemsSelectSingleItem方法具有附加的可选参数,其中之一是一个Sitecore.Data.Items.Item作为contextNode.

将项目作为第二个参数传递使用该项目作为XPath查询的上下文.

var query =
    string.Format(
        "./ancestor::*[@@templateid='{0}']",
        id.ToString());
ancestor =
    Sitecore
        .Data
        .Query
        .Query
        .SelectSingleItem(query, item);
Run Code Online (Sandbox Code Playgroud)