我有困难写生成面包屑试制出的节点结构的模板。它不能正常工作到现在为止,没有在我的思想应该怎么走项目路径的一些缺陷。生成与XSL一个面包屑从节点结构
考虑下面的页面结构:
<!-- ===== SITE PAGE STRUCTURE ===================================== -->
<index>
<item section="home" id="index"></item>
<item section="service" id="index">
<item id="content-management-systems">
<item id="p1-1"/>
<item id="p1-2"/>
<item id="p1-3"/>
</item>
<item id="online-stores"></item>
<item id="search-engines-and-ir"></item>
<item id="web-applications"></item>
</item>
<item section="solutions" id="index">
<item id="document-clustering"></item>
</item>
<item section="company" id="index">
<item section="company" id="about"></item>
<item section="company" id="philosophy" ></item>
...
</item>
...
</item>
本网站指数代表了其层次结构的XML内容页(认为它是一个菜单)网站结构。它包含部分,代表的网站部分就像家庭,公司,服务,解决方案等。这些部分可以包含分部分与页面,或只是普通的内容页面。内容页面(其标题,文本内容等xml内容)由项目树中的@id属性标识。 @id属性主要用于获取将呈现为html的整个页面的内容。 痕迹导航模板使用项目节点@Id属性让页面(这将在导航条来显示)的称号。
我尝试实现以下模板,步行通过检查树中的目标部分属性@section和目标页面属性@id。我希望它走线,直到目标item_target通过比较祖先@section属性,并与该轴的每个节点的item_target $的@id找到。
例如:属性* $ item_section =服务*和页面ID *目标,item_target = P1-1 *现在应该递归 “走” 到部分分支 “服务”(深度为1),检查是否目标页面@id在此级别上找到。在这种情况下,它没有找到,所以它使下一recurive调用(通过应用模板)到下一个项目节点级(在这种情况下,这将是内容管理系统,有目标项目页面P1 -1被发现,所以跟踪过程完成:
结果应该是这样的:
首页>>服务>>内容管理系统>> P1-1
但不幸的是它是没有正确的工作,至少不是在所有情况下,也可能更容易解决把它作为一个递归模板,从顶层(0级)到目标页面(项目节点)作为一个叶子。
<!-- walk item path to generate a breadcrumb trail -->
<xsl:template name="breadcrumb">
<a>
<xsl:attribute name="href">
<xsl:text>/</xsl:text>
<xsl:value-of select="$req-lg"/>
<xsl:text>/home/index</xsl:text>
</xsl:attribute>
<xsl:value-of select="'Home'"/>
</a>
<xsl:apply-templates select="$content/site/index" mode="Item-Path">
<xsl:with-param name="item_section" select="'service'"/>
<xsl:with-param name="item_target" select="'search-engines-and-ir'"/>
<xsl:with-param name="depth" select="0"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="item" mode="Item-Path">
<xsl:param name="item_section" />
<xsl:param name="item_target" />
<xsl:param name="depth" />
<!--
depth=<xsl:value-of select="$depth"/>
count=<xsl:value-of select="count(./node())"/><br/>
-->
<xsl:variable name="cur-id" select="@id"/>
<xsl:variable name="cur-section" select="@section"/>
<xsl:choose>
<xsl:when test="@id=$item_target">
>>
<a>
<xsl:attribute name="href">
<xsl:text>/</xsl:text>
<!-- req-lg: global langauge variable -->
<xsl:value-of select="$req-lg"/>
<xsl:text>/</xsl:text>
<xsl:value-of select="$item_section"/>
<xsl:text>/</xsl:text>
<xsl:if test="$depth = 2">
<xsl:value-of select="../@id"/>
<xsl:text>/</xsl:text>
</xsl:if>
<xsl:value-of select="@id"/>
</xsl:attribute>
<xsl:value-of
select="$content/page[@id=$cur-id]/title"/>
</a>
</xsl:when>
<xsl:otherwise>
<xsl:if test="ancestor-or-self::item/@section = $item_section and count(./node()) > 0">
>>:
<a>
<xsl:attribute name="href">
<xsl:text>/</xsl:text>
<!-- req-lg: global langauge variable -->
<xsl:value-of select="$req-lg"/>
<xsl:text>/</xsl:text>
<xsl:value-of select="$item_section"/>
<xsl:text>/</xsl:text>
<xsl:if test="$depth = 2">
<xsl:value-of select="../@id"/>
<xsl:text>/</xsl:text>
</xsl:if>
<xsl:value-of select="@id"/>
</xsl:attribute>
<xsl:value-of
select="$content/page[@id=$cur-id and @section=$item_section]/title"/>
</a>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates select="item" mode="Item-Path">
<xsl:with-param name="item_section" select="$item_section"/>
<xsl:with-param name="item_target" select="$item_target"/>
<xsl:with-param name="depth" select="$depth + 1"/>
</xsl:apply-templates>
</xsl:template>
,以便在模板中的硬编码参数面包屑,目标节=“服务”和目标网页=“搜索引擎和-IR”,我希望像
回家输出>>服务>>搜索引擎和红外
但输出
首页>>服务>>内容管理系统>> S目录操作搜索,引擎和红外
这显然是不正确的。
任何人都可以给我一个提示如何解决这个问题?避免深度检查会更加优雅,但到现在为止,我无法想到其他方式,我确信有更优雅的解决方案。
我使用XSLT 1.0(通过PHP5的libxml)。
希望我的问题很清楚,如果不是,请提问:-)感谢您的帮助!
的问题是不明确的。请编辑并解释在源XML文档中如何表示父子关系。另外,请解释给出了什么以及必须在树*的条款中产生什么。 –
@ Dimitre Novatchev:对不起,如果我的问题不清楚。我编辑了我的问题,并试图更准确地看到xml树和xsl模板代码之间的文本。希望它更清楚我试图实现的目标...... –
在您的输入文档中,服务不是家中的孩子。你的预期产出不应该简单地......服务>>搜索引擎和搜索引擎? –