[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
Add a no-op template for any SB that isn't the first in the sequence, eg:
<xsl:template match="SB[preceding-sibling::*[1][self::SB]]" priority="2"/>
On 6/13/06, Trevor Nicholls <trevor@xxxxxxxxxxxxxxxxxx> wrote:
Re: [xsl] Combining consecutive siblings
Subject: Re: [xsl] Combining consecutive siblings From: "andrew welch" <andrew.j.welch@xxxxxxxxx> Date: Tue, 13 Jun 2006 09:07:46 +0100 |
In your CELL matching template you are applying-templates to all SB children, rather than just the first SB child in each sequence of SB's.
Add a no-op template for any SB that isn't the first in the sequence, eg:
<xsl:template match="CELL"> <td><xsl:apply-templates select="SB"/></td> </xsl:template>
<xsl:template match="SB[preceding-sibling::*[1][self::SB]]" priority="2"/>
cheers andrew
On 6/13/06, Trevor Nicholls <trevor@xxxxxxxxxxxxxxxxxx> wrote:
Hello
In some contexts the XML I am processing contains a run of consecutive elements which I want to merge into a single element in the output XML. I have adapted a technique which I found in the archives (it was called "grouping consecutive elements" then, and didn't do precisely what I wanted, but seemed to be the right approach).
Here's a cut down piece of XML which highlights the problem: -------- <?xml version="1.0" encoding="UTF-8"?> <root> <Body>If you add this to the enquiry:</Body> <TABLE><ROW><CELL> <SB>where </SB> <SB> <File>client</File> has <Field>country</Field>="NZ"</SB> <SB> and <Field>city</Field>="WELLINGTON"</SB> <SB> and <Field>name</Field> matches (plum* ~plumlee*)</SB> <SB> and val(<Field>street</Field>[1,pos(" ",<Field>street</Field>)-1]) > 0</SB> <SB>list</SB> <SB> <File>client</File>:<Field>name</Field> <Field>address</Field></SB> </CELL></ROW></TABLE> </root> --------
The requirement is to collapse all the consecutive <SB> elements into a single <syntax> element, with newlines in the output reflecting the multiple <SB> nodes, and retaining any lower level structure.
This is the XSL I have arrived at: -------- <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xsl:output method="xml" encoding="UTF-8"/>
<xsl:template match="root"> <document><xsl:apply-templates /></document> </xsl:template>
<xsl:template match="Body"> <xsl:call-template name="nl" /> <para><xsl:apply-templates /></para> </xsl:template>
<xsl:template match="TABLE"> <xsl:call-template name="nl" /> <xsl:element name="table"> <tbody><xsl:apply-templates select="ROW[CELL]" /></tbody> </xsl:element> </xsl:template>
<xsl:template match="ROW"> <tr><xsl:apply-templates /></tr> </xsl:template>
<xsl:template match="CELL"> <td><xsl:apply-templates /></td> </xsl:template>
<xsl:template match="SB"> <xsl:call-template name="nl" /> <syntax> <xsl:apply-templates select="child::node()" mode="syn"/> <xsl:apply-templates select="following-sibling::*[1][self::SB]" mode="more" /> </syntax> <xsl:apply-templates select="following-sibling::*[not(self::SB)][1]" /> </xsl:template>
<xsl:template match="SB" mode="more"> <xsl:call-template name="nl" /> <xsl:apply-templates select="child::node()" mode="syn"/> <xsl:apply-templates select="following-sibling::*[1][self::SB]" mode="more" /> </xsl:template>
<xsl:template match="File | Field" mode="syn"> <f><xsl:apply-templates /></f> </xsl:template>
<xsl:template name="nl"><xsl:text>
</xsl:text></xsl:template>
</xsl:stylesheet> --------
The original templates were posted (by Dr Kay, to whom thanks) as an example of processing elements using "horizontal" recursion: I'll include them here because someone may instantly see where my adaptation is in error:
-------- <xsl:template match="b"> <b> <xsl:copy-of select="."/> <xsl:apply-templates select="following-sibling::*[1][self::b]" mode="more"/> </b> <xsl:apply-templates select="following-sibling::[not(self::b)][1]"/> </xsl:template>
<xsl:template match="b" mode="more"> <xsl:copy-of select="."/> <xsl:apply-templates select="following-sibling::*[1][self::b]" mode="more"/> </xsl:template> --------
Apart from the obvious edits due to my input repeat being <SB> and my output "container" being <syntax>, I had to make two other changes: this original template copied the repeated elements (copy-of select=".") which gave me output XML of <syntax><SB>..</SB><SB>..</SB><SB>..</SB></syntax> and not <syntax>...</syntax>, secondly when I replaced the copy-of with <apply-templates select=child::node() /> to retain the low-level structure I found that the mode="more" was being carried through, hence the mode="syn" in the stylesheet above.
The resultant output is wrong because instead of giving me one syntax element containing the content of all the consecutive SB elements, I have as many syntax elements as SBs, gradually reducing in length, viz:
-------- <?xml version="1.0" encoding="UTF-8"?><document xmlns:xs="http://www.w3.org/2001/XMLSchema"> <para>If you add this to the enquiry:</para> <table><tbody><tr><td> <syntax>where <f>client</f> has <f>country</f>="NZ" and <f>city</f>="WELLINGTON" and <f>name</f> matches (plum* ~plumlee*) and val(<f>street</f>[1,pos(" ",<f>street</f>)-1]) > 0 list <f>client</f>:<f>name</f><f>address</f></syntax> <syntax><f>client</f> has <f>country</f>="NZ" and <f>city</f>="WELLINGTON" and <f>name</f> matches (plum* ~plumlee*) and val(<f>street</f>[1,pos(" ",<f>street</f>)-1]) > 0 list <f>client</f>:<f>name</f><f>address</f></syntax> <syntax> and <f>city</f>="WELLINGTON" and <f>name</f> matches (plum* ~plumlee*) and val(<f>street</f>[1,pos(" ",<f>street</f>)-1]) > 0 list <f>client</f>:<f>name</f><f>address</f></syntax> <syntax> and <f>name</f> matches (plum* ~plumlee*) and val(<f>street</f>[1,pos(" ",<f>street</f>)-1]) > 0 list <f>client</f>:<f>name</f><f>address</f></syntax> <syntax> and val(<f>street</f>[1,pos(" ",<f>street</f>)-1]) > 0 list <f>client</f>:<f>name</f><f>address</f></syntax> <syntax>list <f>client</f>:<f>name</f><f>address</f></syntax> <syntax><f>client</f>:<f>name</f><f>address</f></syntax> </td></tr></tbody></table></document> --------
What am I doing wrong? Can anyone help?
Cheers Trevor
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Combining consecutive sibling, Trevor Nicholls | Thread | RE: [xsl] Combining consecutive sib, Trevor Nicholls |
[xsl] Final Announcement: XML Pragu, James Fuller | Date | Re: [xsl] Final Announcement: XML P, David Carlisle |
Month |