我的父项/子项依赖项很少:
第1项 - >第2项 - >项目3
他们有相同名称的字段:“主要信息”。他们中的一些人填写了这个字段,其中一些字段带有空的“主要信息”。主要目标:如果选择了填写“主要信息”的页面 - 显示此信息。如果选择了空“主要信息”的页面 - 显示来自祖先的信息。 所以我有渲染:
<xsl:variable name="home" select="$sc_currentitem/ancestor-or-self::*[contains(@template, 'page') and @Main Info != '']" />
<!-- entry point -->
<xsl:template match="*">
<xsl:apply-templates select="$home" mode="main"/>
</xsl:template>
<xsl:template match="*" mode="main">
<sc:text field="Right Footer Text" />
</xsl:template>
这没什么。
<xsl:variable name="home" select="$sc_currentitem/ancestor-or-self::*[contains(@template, 'page')]" />
<xsl:template match="*">
<xsl:apply-templates select="$home" mode="main"/>
</xsl:template>
<xsl:template match="*" mode="main">
<sc:text field="Right Footer Text" />
</xsl:template>
这显示了所选项目的每个祖先的“主要信息”。
我怎样才能获得一个“主要信息”?如果此字段不为空,则来自所选项目,或填充“主要信息”的第一个父项目。
答案 0 :(得分:2)
我真的相信这说明了为什么你应该考虑用C#编写组件而不是浪费时间试图通过XSLT“破解”解决方案。当然,如果你愿意,你可以编写自己的扩展 - 但是让我们考虑一下开始这么简单的代码。
在您的.ASCX文件中,您将拥有:
<sc:Text runat="server" ID="sctMainInfo" Field="main info" />
在你的.cs codebehind / codebeside中:
Sitecore.Data.Item myItem = Sitecore.Context.Item; // Should be your Datasource item
while (string.IsNullOrWhiteSpace(myItem["main info"]))
{
myItem = myItem.Parent; // you need to add a check here,
// so you don't move up past your Site Root node
}
sctMainInfo.Item = myItem;
远比组合的XSLT / XSL Helper方法简单,性能会好很多。
最后一件事。渲染的前提是有问题的。您不应该实际爬行项目层次结构来查找组件的内容,而是阻止执行M / V测试或个性化组件的任何可能性。然而,这是一个不同日子的故事。
答案 1 :(得分:1)
在性能方面,您可能不想使用ancestor-or-self
选择器。如果你有很多物品和深树,它对性能有害。
我想我要像这样创建一个<xsl:choose>
:
<xsl:choose>
<xsl:when test="sc:fld('main info',.)!=''">
<sc:text field="main info" select="." /> <!-- Display main info from item -->
</xsl:when>
<xsl:otherwise>
<sc:text field="main info" select=".." /> <!-- Display main info from parent -->
</xsl:otherwise>
</xsl:choose>
当然,如果有可能它不是父母,而父母的父母(等等)有主要信息,我会通过创建自己的XSL扩展来简化它。
您可以通过Jens Mikkelsen在此article上阅读有关XSL Extensions的更多信息。