Re: [xsl] Aligning Parallel Columns

Subject: Re: [xsl] Aligning Parallel Columns
From: Michael Kay <mike@xxxxxxxxxxxx>
Date: Sat, 15 Jan 2011 16:43:47 +0000
OK, let's see whether it can be done if the name attribute are randomized, so that you can't rely on them for sorting. Is that what you're looking for?

This immediately raises the question of what happens if one sequence is (A, Z, B) and the other is (A, X, B) - what order do Z and X appear in?

I think I would tackle it as follows. Call a para an anchor para if there is a para in the other list with the same name. For each anchor para in the first list, output a table row containing it and its twin from the other list. Then output all the non-anchor paras from the first list up to the next anchor, then all the non-anchor paras from the second list up to the next anchor, then the next anchor pair and so on.

First identify the keys of the anchor rows:

<xsl:variable name="anchors" as="xs:string*">
<xsl:for-each-group select="//p/@name" group-by=".">
<xsl:if test="count(current-group() = 2)">
<xsl:sequence select="string(.)"/>
</
</
</

Then do something like this:

for-each select="div[@id='ch1']/para[@name = $anchors]"
  output row containing the pair of lines for this anchor
  output-inserted-lines(list 1)
  output-inserted-lines(list 2)
/for-each

The function output-inserted-lines is recursive, something like this

<xsl:function name="f:output-inserted-lines">
<xsl:param name="start" as="node()"/>
<xsl:variable name="next" as="$start/following-sibling::*[1]">
<xsl:if test="not($next/@name = $anchors)">
    (output this line)
<xsl:sequence select="f:output-inserted-lines($next)"/>
</
</

Having done that, I'm wondering whether there's a solution using the new xsl:merge instruction in XSLT 3.0 (implemented in Saxon 9.3). This would depend on allocating computed merge keys: perhaps a three part key (a) a number I indicating that this is the Nth anchor row, (b) a number J indicating which of the input lists the para comes from, (c) a number K indicating that there are K paras since the last anchor para. It's probably just as complex as the solution above.

Michael Kay
Saxonica



On 15/01/2011 12:11, Jeroen Hellingman wrote:
I have two texts, one being the translation of the other. I want to
print them side by side in an HTML table, such that translated
paragraphs are aligned.

Sometimes, additional paragraphs have been added in the translation, and
sometimes, paragraphs have been merged, so the relationship is not
always one-on-one, but corresponding paragraphs will have the same id
in both documents.

e.g., documents one and two:

         <div id="ch1">
             <p name="a1">Eerste Alinea.</p>
             <p name="a1.1">Zomaar ertussen.</p>
             <p name="a2">Tweede Alinea.</p>
             <p name="a3">Derde Alinea.</p>
         </div>

         <div id="ch2">
             <p name="a1">First Paragraph.</p>
             <p name="a2">Second Paragraph.</p>
             <p name="a2.1">Something added here.</p>
             <p name="a3">Third Paragraph.</p>
         </div>

And the result I wish to produce looks something like:

     <table>
         <tr><td>Eerste Alinea.</td>   <td>First Paragraph.</td></tr>
         <tr><td>Zomaar ertussen.</td><td/></tr>
         <tr><td>Tweede Alinea.</td>    <td>Second Paragraph.</td></tr>
         <tr><td/>                        <td>Something added here.</td></tr>
         <tr><td>Derde Alinea.</td>    <td>Third Paragraph.</td></tr>
     </table>

Technically, this is a kind of full outer join of both documents.

Any suggestions on how to tackle this with XSLT (2.0 welcome)?


Jeroen Hellingman

Current Thread