I'm developping a custom CQWP using a custom ContentQueryMain.xsl, I am using a list structure with which I would like to have a separator creating a new list each three items. Here is the code of the template:
<xsl:template name="CustomGroupTemplateSimple2">
<ul>
<li>
<ul class="liste1">
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/>
<xsl:for-each select="$Rows">
<xsl:call-template name="OuterTemplate.CallPresenceStatusIconTemplate"/>
<li>
test
</li>
<xsl:if test="position() mod 3 = 0">
</ul>
</li>
<li>
<ul class="separator">
</xsl:if>
</xsl:for-each>
</ul>
</li>
</ul>
</xsl:template>
The separator is:
</ul>
</li>
<li>
<ul class="separator">
is responsible of the webpart error raised. The following code is working perfectly:
<xsl:template name="CustomGroupTemplateSimple2">
<ul>
<li>
<ul class="liste1">
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/>
<xsl:for-each select="$Rows">
<xsl:call-template name="OuterTemplate.CallPresenceStatusIconTemplate"/>
<li>
test
</li>
开发者_Go百科 <xsl:if test="position() mod 3 = 0">
SEPARATOR
</xsl:if>
</xsl:for-each>
</ul>
</li>
</ul>
</xsl:template>
And when I DIRECTLY replace the "SEPARATOR" with:
</ul>
</li>
<li>
<ul class="separator">
in the aspx page (after compilation), everything is perfectly working, too.
Therefore, I am really lost with this situation as I really need this separator.
Thank you very much
The reason for the error is obvious: Any XSLT stylesheet must be a well-formed XML document and this provided stylesheet isn't. This is why even the XML parser that the XSLT processor uses to get its stylesheet module, raises a non-well-formedness exception.
In particular, this fragment:
<xsl:if test="position() mod 3 = 0">
</ul>
</li>
<li>
<ul class="separator">
</xsl:if>
isnt a well-formed XML fragment, becausethere isn't any start tag for the end tags </ul>
and </li>
.
Finally, here is a correct example of such positional grouping:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="num[position() mod 3 = 1]">
<group>
<xsl:copy-of select=
". | following-sibling::*[not(position() > 2)]"/>
</group>
</xsl:template>
<xsl:template match="num"/>
</xsl:stylesheet>
when this transformation is applied to the following XML document:
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
the wanted, correctly grouped result is produced:
<nums>
<group>
<num>01</num>
<num>02</num>
<num>03</num>
</group>
<group>
<num>04</num>
<num>05</num>
<num>06</num>
</group>
<group>
<num>07</num>
<num>08</num>
<num>09</num>
</group>
<group>
<num>10</num>
</group>
</nums>
At a surface level, your stylesheet is invalid because it is not well-formed XML.
At a deeper level, you have failed to understand that XSLT deals with XML as a tree of nodes. You are trying to think of <a>
and </a>
as two separate instructions, one of which writes a start tag to the output, the other writing an end tag to the output. That's the wrong mental model of how XSLT works. In fact <a>...</a>
is the lexical representation of an element node in the stylesheet; the element node in the stylesheet is a single instruction, whose effect when evaluated is to write an element node to the result tree. Nodes are indivisible, and you can't separate the operation of writing a node into two parts, each of which writes half a node.
Your problem is a grouping problem. Grouping problems are much easier to solve in XSLT 2.0 than in 1.0 - but solutions are always possible even in 1.0, without departing from the XSLT processing model.
the only way to achieve the functionality you are asking for is the option 2 suggested by you put all the closing tag in xsl text and render it. other wise you can not plase the closing tag in if condition that would be treated as error
I have found the solution:
In fact the problem was that inside a for-each, you cannot insert unmatched tags, therefore, to do it, you have to wrap them into:
<xsl:text disable-output-escaping="yes"><![CDATA[
any HTML in here will not be validated
]]></xsl:text>
精彩评论