克服 xsl 中的未闭合标签 [英] Overcoming unclosed tags in xsl
问题描述
我正在开发一个下拉菜单,该菜单从 Sharepoint 列表中提取数据并使用 xsl 进行样式设置.html结构是一个简单的无序列表
I'm working on a drop down menu that pulls data from a Sharepoint list and is styled with xsl. The html structure is a simple unordered list
<ul><li>parent page</li><ul><li>sub page 1</li><li>sub page2</li></ul></ul>
xsl 测试列表中的项目是父页面还是子页面以及子页面编号是什么.父页面有一个编号,因此可以将所需的子页面附加到正确的父页面.
The xsl tests if an item in the list is a parent page or a sub page and what the sub page number is. Parent pages have a number so the desired sub pages can be attached to the correct parent page.
每个项目的基本 xsl 是这样的:
The basic xsl for each item is this:
<xsl:for-each select="//Data/Row">
<xsl:if test="./@Page_x0020_type = 0">
<li >
<a>
<xsl:attribute name="href">
<xsl:value-of
select="./@Page_x002f_link_x0020_url"/>
</xsl:attribute>
<xsl:value-of select="./@Title0"/>
</a>
</li>
</xsl:if>
我希望 xsl 等同于:如果是子页面,则在项目前添加 ul 标签,如果是父页面下的最后一个子页面,则添加结束 ul 标签.
I want the xsl to equate to this: If it's a sub page, precede the item with a ul tag and if it's the last sub page under a parent, add a closing ul tag.
如何解决 xsl 不允许我添加未关闭的 ul 标签的事实,因为它(正确地)不知道该标签是否会关闭?
How do I get around the fact that xsl won't let me add an unclosed ul tag because it (rightly) doesn't know if the tag is going to get closed?
XML
<Field Type="Text"
DisplayName="Page/link url"
Required="FALSE"
MaxLength="255"
Name="Page_x002f_link_x0020_url"/>
<Field ReadOnly="TRUE"
Type="Computed"
Name="LinkTitle"
DisplayName="Page number"/>
<Field Type="Text"
DisplayName="Title"
Required="FALSE"
MaxLength="255"
Name="Title0"/>
<Field Type="Choice"
DisplayName="Page type"
Required="FALSE"
Format="RadioButtons"
FillInChoice="FALSE"
Name="Page_x0020_type">
<CHOICES>
<CHOICE>0</CHOICE>
<CHOICE>1</CHOICE>
</CHOICES>
<DefaultFormula>=0</DefaultFormula>
<DefaultFormulaValue/>
</Field>
<Field Type="Text"
DisplayName="Sub page number"
Required="FALSE"
MaxLength="2"
Name="Sub_x0020_page_x0020_number"/>
<Field Type="Text"
DisplayName="Parent page number"
Required="FALSE"
MaxLength="1"
Name="Parent_x0020_page_x0020_number">
<Default>0</Default>
</Field>
</Schema>
<Data ItemCount="1">
<Row Page_x002f_link_x0020_url=""
LinkTitle=""
Title0=""
Page_x0020_type=""
Sub_x0020_page_x0020_number=""
Parent_x0020_page_x0020_number=""
ul=""
_x003c_li_x003e__x003c_a_x003e_=""
_x003c__x002f_a_x003e__x003c__x0=""
_x003c_ul_x003e__x003c_li_x003e_=""
_x003c__x002f_a_x003e__x003c__x00=""
_x003c__x002f_a_x003e__x003c__x01=""/>
更新:
页面类型:- 父
- parent1
- 子页面 1 - 需要以
- ...
- 子页面 1
开头 - 中间子页面-(编号设置排序顺序-html与父页面相同)
- 子页面#
- 组中的最后一个子页面 - 需要以
</ul>
结尾
- Parent
<li>parent1</li>
- Sub page 1 - needs to start with a
<ul>...<li>sub page 1</li>
- Middle sub pages-(numbered to set sort order-html same as parent page)
<li>sub page #</li>
- Last sub page in group - needs to end with a
</ul>
UPDATE:
Page types:推荐答案
我希望 xsl 等同于这个:如果它是一个子页面,在项目之前添加一个 ul 标签,如果它是父页面下的最后一个子页面,添加一个结束 ul 标签.
I want the xsl to equate to this: If it's a sub page, precede the item with a ul tag and if it's the last sub page under a parent, add a closing ul tag.
你想错了.XSLT 不编写标签,它编写节点树.您不能将半个节点写入结果树.
You're thinking the wrong way. XSLT doesn't write tags, it writes a tree of nodes. You can't write half a node to the result tree.
在 XSLT 2.0 中,您可能可以使用带有 group-starting-with 属性的 xsl:for-each-group 来做您想做的事 - 我不能具体说明,因为您还没有足够清楚地说明问题,但它是大概是这样的:
In XSLT 2.0 you can probably do what you want using xsl:for-each-group with the group-starting-with attribute - I can't be specific, because you haven't specified the problem clearly enough, but it's probably something like this:
<xsl:template match="parent">
<xsl:for-each-group select="*" group-starting-with="li[....]">
<ul>
<xsl:copy-of select="current-group()"/>
</ul>
</xsl:for-each-group>
</xsl:template>
如果您坚持使用 XSLT 1.0 那么它会更困难:我将使用一种称为兄弟递归"的技术,在该技术中,您将模板应用于第一个孩子,然后将模板应用于下一个兄弟,并且很快.父级的模板规则是这样的:
If you're stuck with XSLT 1.0 then it will be more difficult: I would use a technique called "sibling recursion" in which you apply-templates to the first child, which in turn applies templates to the next sibling, and so on. The template rule for the parent does this:
<xsl:template match="parent">
<xsl:apply-templates select="*[1]"/>
</xsl:template>
作为组中第一个兄弟姐妹的模板规则是这样的:
The template rule for a sibling that is to be the first in a group does this:
<xsl:template match="parent/*[ (: where this is the first in a group :) ]">
<group>
<xsl:copy-of select="."/>
<xsl:apply-templates select="following-sibling::*[1]"/>
</group>
<xsl:apply-templates select="following-sibling::*[(* start of next group *)][1]"/>
</xsl:template>
其他兄弟姐妹的模板规则确实如此:
and the template rule for other siblings does:
<xsl:template match="parent/*">
<xsl:copy-of select="."/>
<xsl:apply-templates select="following-sibling::*[1]"/>
</xsl:template>
即使对于有经验的 XSLT 开发人员来说,细节也可能很棘手.
The details can be tricky even for experienced XSLT developers.
这篇关于克服 xsl 中的未闭合标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!