We use xsl-fo to generate pdf.
We want the pdf to be pdf-ua-compliant.
We use veraPDF for validation this standard.
When there is a table-header that has horizontal spanned cells, it complains about rule 7.5-1:
"In a table not organized with Headers attributes and IDs, a TH cell does not contain a Scope attribute"
Normally each header cell has an id, that we can refer to in body-cells by using rx:header-idref
(a renderx-xep specific solution, see comments in this question for more context)
But with spanned header cells this fails because there are body-cells that have no corresponding header-cell.
the second cell of the first body-row with "R ≤ 10 (hb +hw)" is missing it's header-cell to reference it's id.
How can this be resolved?
EDIT: for better understanding this is the source xml:
<table>
<tgroup cols="4" align="left">
<colspec colnum="1" colwidth="28.1*" colname="col1"/>
<colspec colnum="2" colwidth="34.3*" colname="col2"/>
<colspec colnum="3" colwidth="20*" colname="col3"/>
<colspec colnum="4" colwidth="17.7*" colname="col4"/>
<thead valign="bottom">
<row rowsep="1">
<entry namest="col1" nameend="col2" valign="top" align="center" colname="col1" rotate="0" morerows="1" colsep="1">
<Al>afstand</Al>
</entry>
<entry namest="col3" nameend="col4" valign="top" align="left" colname="col3" rotate="0" colsep="1">
<Al>minimum aantal metingen <i>N</i></Al>
</entry>
</row>
<row rowsep="1">
<entry valign="top" align="left" colname="col3" rotate="0" colsep="1">
<Al>zonder afscherming</Al>
</entry>
<entry valign="top" align="left" colname="col4" rotate="0" colsep="1">
<Al>met afscherming</Al>
</entry>
</row>
</thead>
<tbody valign="top">
<row rowsep="1">
<entry valign="top" align="left" colname="col1" rotate="0" colsep="1"/>
<entry valign="top" align="left" colname="col2" rotate="0" colsep="1">
<Al><i>R</i> ≤ 10 (<i>h<sub>b</sub></i> + <i>h<sub>w</sub></i>)</Al>
</entry>
<entry valign="top" align="left" colname="col3" rotate="0" colsep="1">
<Al>1</Al>
</entry>
<entry valign="top" align="left" colname="col4" rotate="0" colsep="1">
<Al>1</Al>
</entry>
</row>
<row rowsep="1">
<entry valign="top" align="left" colname="col1" rotate="0" colsep="1">
<Al>10 (<i>h<sub>b</sub></i> + <i>h<sub>w</sub></i>) <</Al>
</entry>
<entry valign="top" align="left" colname="col2" rotate="0" colsep="1">
<Al><i>R</i> ≤ 20 (<i>h<sub>b</sub></i> + <i>h<sub>w</sub></i>)</Al>
</entry>
<entry valign="top" align="left" colname="col3" rotate="0" colsep="1">
<Al>1</Al>
</entry>
<entry valign="top" align="left" colname="col4" rotate="0" colsep="1">
<Al>2</Al>
</entry>
</row>
<row rowsep="1">
<entry valign="top" align="left" colname="col1" rotate="0" colsep="1">
<Al>20 (<i>h<sub>b</sub></i> + <i>h<sub>w</sub></i>) <</Al>
</entry>
<entry valign="top" align="left" colname="col2" rotate="0" colsep="1">
<Al>
<i>R</i>
</Al>
</entry>
<entry valign="top" align="left" colname="col3" rotate="0" colsep="1">
<Al>2</Al>
</entry>
<entry valign="top" align="left" colname="col4" rotate="0" colsep="1">
<Al>3</Al>
</entry>
</row>
</tbody>
</tgroup>
</table>
And this is a snippet of the current xslt:
<xsl:template match="row/entry" mode="content">
<xsl:param name="inThead" as="xs:boolean" tunnel="yes"/>
<fo:table-cell>
<xsl:choose>
<xsl:when test="$inThead">
<!-- In de thead delen we aleeen id's uit aan die entries die als eerste voorkomen met hun betreffende colname, zodat id uniek is. -->
<xsl:variable name="colname" select="@colname"/>
<xsl:if test="not(parent::row/preceding-sibling::row/entry[@colname=$colname])">
<xsl:attribute name="id" select="@colname"/>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="rx:header-idref" select="@colname"/>
</xsl:otherwise>
</xsl:choose>
<!-- here some other logic -->
</fo:table-cell>
</xsl:template>
To me the question without markup is a bit unclear however note that there is nothing that stops multiple body cells from referencing the same header cell. So the second cell should reference the spanned header cell. As should all the body cells in columns 1 and 2.
Note that the rx:header-idref can be a comma separated list of id's. This is the order in which they should be read. So in the third cell in that first row, you would reference the id's of the spanned top header and the one below that does not span. This same technique would apply to row headers. As in you could have:
@rx:header-idref="col3-4head1spanned, col3head2"
and
@rx:header-idref="col3-4head1spanned, col4head2"
as an image of what I mean: