开发者

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>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜