XSLT preceding-sibling limitation and workaround
I'm having problem with preceding-sibling. Is this really working?
XSL looks something like this:
<stored-procedure id="search-algorithm-parent-child">
<xsl:stylesheet version="1.0" xmlns:spbc="urn:lsapps.spbcontext" xmlns:user="http://www.lodestarcorp.com" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="node()|/|@*">
<query name="CMNUALGPARENTCHILD">
<sql>
SELECT
parent.UIDALGLIBPARENTDTL as UIDPARENT,
parent.PARENTCHANNELID as VMCHANNELNUMBER,
parent.UOMCODE as UOM,
child.CHILDDCFLOW AS DCFLOW,
FROM
##Q.NUALGLIBPARENTDTL parent,
##Q.NUALGLIBCHILDDTL child
WHERE
child.UIDALGLIBPARENTDTL = parent.UIDALGLIBPARENTDTL
AND parent.UIDALGLIBRARY = '<xsl:value-of select="@UIDALGLIBRARY"/>'
ORDER BY UIDPARENT
</sql>
</query>
</xsl:template>
</xsl:stylesheet>
</stored-procedure>
I dont't know how XML looks like when I pass above XSL to LsdbCommand in my asp like this:
var xmlTable5 = LsdbCommand("LSDB.search-algorithm-parent-child", PrefixParams1.valueOf());
I'm assuming that XML data will be something like this (ordered by UIDPARENT):
<CMNUALGPARENTCHILD>
<someNode>
<UIDPARENT>21</UIDPARENT>
<VMCHANNELNUMBER>123</VMCHANNELNUMBER>
<UOM>5<UOM>
<DCFLOW>R<DCFLOW>
</someNode>
<someNode>
<UIDPARENT>21</UIDPARENT>
<VMCHANNELNUMBER>123</VMCHANNELNUMBER>
<UOM>5<UOM>
<DCFLOW>R<DCFLOW>
</someNode>
...
</CMNUALGPARENTCHILD>
For now, my concern is the UIDPARENT.. What I'm sure of is that result would have the following UIDPARENT..(in order)
21
21
21
81
81
81
Now, in the asp, I call this
tTable5 = ProcessXsl(xmlTable5, XmlFreeFile("../zAlgorithmLibrary/AlgorithmParentChild.xslt"));
where AlgorithmParentChild.xslt is simply
<x:stylesheet version="1.0"
xmlns:x="http://www.w3.org/1999/XSL/Transform"
xmlns:i="urn:ls-i18n-formatter"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:user="http://www.lodestarcorp.com/user"
exclude-result-prefixes="x i ms user">
<x:param name="Portal">N</x:param>
<x:param 开发者_如何学Cname="Include">ALL</x:param>
<x:param name="OrderParams"></x:param>
<x:param name="FromParam"></x:param>
<x:param name="ROWPERPAGE">25</x:param>
<x:param name="AllowEdit"></x:param>
<x:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
<x:template match="/">
<table class="FormTable">
<x:for-each select="//CMNUALGPARENTCHILD">
<tr>
<td>current <x:value-of select="@UIDPARENT"/></td>
<td>previous <x:value-of select="preceding-sibling::node()/@UIDPARENT"/></td>
<td>next <x:value-of select="following-sibling::node()/@UIDPARENT"/></td>
</tr>
</x:for-each>
</table>
</x:template>
<x:include href="../controls/MultiSortImages.xslt"/>
<x:include href="../controls/LockedColumns.xslt"/>
</x:stylesheet>
main table looks like this
current 21 previous next 21
current 21 previous 21 next 21
current 21 previous 21 next 81
current 81 previous 21 next 81
current 81 previous 21 next 81
current 81 previous 21 next
It seems correct on the first three result.. but how come preceding-element failed after the third iteration? It should return the following:
current 21 previous next 21
current 21 previous 21 next 21
current 21 previous 21 next 81
current 81 previous 21 next 81
current 81 previous 81 next 81
current 81 previous 81 next
following-sibling works fine.. are there any known limitations of preceding-sibling? and can you suggest any workaround?
Note that I have also tried appending [position=1]
or [position()]
or simply [1]
on preceding-sibling::node()/@UIDPARENT but it still have the same result..
Please understand that I am new to ASP, XSLT, XSL.. and that I have only put snippets of code and not the entire code..
I just want to understand how preceding-sibling works.. its syntax, everything about it..
As described in the W3C specification:
the preceding-sibling axis contains all the preceding siblings of the context node
What it does not say is that it works in reverse! You need to add a [position()=1]
predicate to the end of your XPath select like this:
<?xml version="1.0" encoding="UTF-8"?>
<x:stylesheet version="1.0"
xmlns:x="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="x">
<x:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
<x:template match="CMNUALGPARENTCHILD">
<table>
<x:for-each select="UIDPARENT">
<tr>
<td>current <x:value-of select="."/></td>
<td>previous <x:value-of select="preceding-sibling::UIDPARENT[position()=1]"/></td>
<td>next <x:value-of select="following-sibling::UIDPARENT[position()=1]"/></td>
</tr>
</x:for-each>
</table>
</x:template>
</x:stylesheet>
I couldn't get the XSL in your question to work. But this works with the XML in your question for me.
Edit: Adding in XML from original question for reference
<CMNUALGPARENTCHILD>
<UIDPARENT>21</UIDPARENT>
<UIDPARENT>21</UIDPARENT>
<UIDPARENT>21</UIDPARENT>
<UIDPARENT>81</UIDPARENT>
<UIDPARENT>81</UIDPARENT>
<UIDPARENT>81</UIDPARENT>
</CMNUALGPARENTCHILD>
精彩评论