XSLT ----> preceding-sibling::

Hello all,
            I am new to XSLT. I have a problem at hand where I have to insert a horizontal rule after a set of similar elements(all similar elements are already in sequential order). I was successful in doing it with the following code

                    <xsl:if test="((preceding-sibling::Insertion/Publication)[last()])">
                        <xsl:if test="not(Publication=((preceding-sibling::Insertion/Publication)[last()]))">
                            <tr>
                                <td colspan="20"><hr/></td>                                        
                            </tr>
                        </xsl:if>
                    </xsl:if>

PROBLEM: Though this works perfectly, whenever the XML file is huge, this code takes a considerable amount of time. I would be very grateful if anyone lead me to a better solution.

NOTE: The solution has to work fast on large XML file.

thanks,
Naveen.
naveen_damerlaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

dualsoulCommented:
hm...i don't understand well what do you want....
but why not to try get all Insertion/Publication one by one? like this:

<xsl:for-each select="Insertion/Publication">
          ...do something here with Publications if you want..........
</xsl:for-each>
<!-- insert horizonatal rule after all elements -->
<tr>
     <td colspan="20"><hr/></td>                                        
</tr>
........... continue processing....................

or didn't get what you want? if so please post more your xslt code, xml source and what do you want to get as output.
0
naveen_damerlaAuthor Commented:
Maybe I wasnt clear enough
                                          Here I go, My XML looks like

           <Insertion>
            <RevisionType></RevisionType>
            <City>Ventura</City>
            <State>CA</State>
            <Publication>Ventura County Star</Publication>
              .
              . //more elements here
            </Insertion>

            <Insertion>
            <RevisionType></RevisionType>
            <City>Ventura</City>
            <State>CA</State>
            <Publication>Anothet County Star</Publication>
             .
             .//more elements here
            </Insertion>

XSLT IS:

     <xsl:if test="((preceding-sibling::Insertion/Publication)[last()])">
                     <xsl:if test="not(Publication=((preceding-sibling::Insertion/Publication)[last()]))">
                            <tr>
                                <td colspan="20"><hr/></td>                                        
                            </tr>
                        </xsl:if>
                    </xsl:if>

What I is want is a horizontal rule """" if """" the publication name is the not the same....and do nothing if it is the same.

That being said my XML files are xtremely huge, so......though the my XSLT works pefectly.....I would like to have a faster alternative.

thanks,
Naveen.
0
rdcproCommented:
Use an XSLT key, and index all the nodes by the aspect you use to determine similarity.  Then you simply have to test if the current node is a new unique node, and insert the horizontal rule:

Using this XML:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="muenchrule.xslt"?>
<insertion>
    <publication>Foo</publication>
    <publication>Foo</publication>
    <publication>Foo</publication>
    <publication>Foo</publication>
    <publication>Foo</publication>
    <publication>Foo</publication>
    <publication>Foo</publication>
    <publication>Bar</publication>
    <publication>Bar</publication>
    <publication>Bar</publication>
    <publication>Bar</publication>
    <publication>Bar</publication>
    <publication>Bar</publication>
    <publication>Bar</publication>
    <publication>Bar</publication>
    <publication>Bar</publication>
    <publication>Snafu</publication>
    <publication>Snafu</publication>
    <publication>Snafu</publication>
    <publication>Snafu</publication>
    <publication>Snafu</publication>
    <publication>Snafu</publication>
</insertion>

And this XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:key name="kRule" match="publication" use="."/>
    <xsl:template match="insertion">
        <Table>
            <xsl:apply-templates select="publication"/>
        </Table>
    </xsl:template>
    <xsl:template match="publication">
        <xsl:if test="generate-id() = generate-id(key('kRule', .)) and position() !=1">
            <tr>
                <td colspan="20"><hr/></td>
            </tr>
        </xsl:if>
            <tr>
                <td colspan="20"><xsl:value-of select="."/></td>
            </tr>
    </xsl:template>
</xsl:stylesheet>

You get a horizontal rule between each unique group, but not before the first one.  This should work fairly quickly for even large sets of nodes.

Regards,
Mike Sharp
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

dualsoulCommented:
>That being said my XML files are xtremely huge, so......though the my XSLT works pefectly.....I would like to have a faster alternative.

may be Mike's suggestion helps you, i think.
 but if you have trouble with perfomance, you should know XSLT is not scalable solution...so if you think your xml files can enlarge in future may be you should think about another architecture...XQuery for instance
0
naveen_damerlaAuthor Commented:
Thank you rdcpro,
 
Your answer sounds really promising(havent tried it)....but I am a completely new to XSLT, this being my 2nd day.......AT the risk of sounding dumb, I would like to ask one more thing....
         If there is already a <xsl:for-each select="Insertions/Insertion">
in the XSLT, how would the answer change

plz note: there will be 500+ elements in the insertions node.


XML looks like:
------------------
<insertions>
        <Insertion>
            <RevisionType></RevisionType>
            <City>Ventura</City>
            <State>CA</State>
            <Publication>Ventura County Star</Publication>
              .
              . //more elements here
            </Insertion>

            <Insertion>
            <RevisionType></RevisionType>
            <City>Ventura</City>
            <State>CA</State>
            <Publication>Anothet County Star</Publication>
             .
             .//more elements here
            </Insertion>

             //500 more insertion elements
 </insertions>

XSLT like:
---------------
<xsl:for-each select="Insertions/Insertion">
                    <xsl:if test="((preceding-sibling::Insertion/Publication)[last()])">
                    <xsl:if test="not(Publication=((preceding-sibling::Insertion/Publication)[last()]))">
                            <!-- inserting horizontal rule-->
                            <tr>
                                <td colspan="20"><hr/></td>                                        
                            </tr>
                        </xsl:if>
                    </xsl:if>
                <tr>
                 <!-- REST OF MY CODE HERE-->
                </tr>


please advise,
thank you rdcpro
Naveen.
0
rdcproCommented:
Well, in that case only the path for the use attribute, and the path to the key() change:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:key name="kRule" match="insertion" use="publication"/>
    <xsl:template match="insertions">
    Number of Insertions:  <xsl:value-of select="count(insertion)"/>
        <Table>
            <xsl:for-each select="insertion">
                <xsl:if test="generate-id() = generate-id(key('kRule', publication)) and position() !=1">
                    <tr>
                        <td colspan="20"><hr/></td>
                    </tr>
                </xsl:if>
                    <tr>
                        <td colspan="20"><xsl:value-of select="publication"/></td>
                    </tr>
                   
            </xsl:for-each>
       </Table>
    </xsl:template>
</xsl:stylesheet>

Note that my XML is not the same case as yours...that is, insertion not Insertion...so watch out.

But with 822 <inserton> elements, it transforms nearly instantly on my desktop.  Parsing the XML is probably going to be a major portion of the overhead, and if you use FreeThreadDomDocument, and caching, you might be surprised how well it scales, assuming efficient XSLT.

This technique is Muenchian grouping, and I have examples and a tutorial on my site:
Code example:
http://dev.rdcpro.com/Members/rdcpro/snippets/columnrowgrouping/
tutorial:
http://dev.rdcpro.com/zones/xml/xslt/faqroot/faq-grouping-1.1

Caching techniques for ASP:
http://dev.rdcpro.com/Members/rdcpro/snippets/cachingtemplates/


Regards,
Mike Sharp
0
naveen_damerlaAuthor Commented:
Thank u rdcpro. I just plugged in the partial code at the right place and PRESTO!!.....evrything works.....and 43 pages of PDF generation was under 2 minutes.

thanks again.....
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Web Languages and Standards

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.