In this possible solution I'm assuming your <spec_span>
and <table_entry>
are children of a <root>
element:
<root>
<spec_span span_start="c2" span_end="c9" span_name="ab12" />
...
<table_entry span_name="ab12">Text Value</table_entry>
</root>
Selecting spec_span
globally you can calculate the colspan
with this XPath 1.0 expression:
substring(//spec_span[@span_name='ab12']/@span_end, 2) -
substring(//spec_span[@span_name='ab12']/@span_start, 2) + 1
You can get the table entry (globally) with:
//table_entry[@span_name='ab12']/text()
In XSLT you can use the root
context (or other context) and adapt those expressions. This stylesheet:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" indent="yes"/>
<xsl:template match="root">
<xsl:variable name="colspan"
select="number(substring(spec_span[@span_name='ab12']/@span_end, 2)) - number(substring(spec_span[@span_name='ab12']/@span_start, 2)) + 1"/>
<xsl:variable name="text"
select="table_entry[@span_name='ab12']/text()" />
<td colspan="{$colspan}">
<xsl:value-of select="$text"/>
</td>
</xsl:template>
</xsl:stylesheet>
will produce the following code as a result:
<td colspan="8">Text Value</td>
A better and more general solution would check for matching pairs of spec_span
and table_entry
(with the same span_name
, ignoring incomplete pairs and generating the code for the others. If you have something like this:
<root>
<spec_span span_start="c2" span_end="c9" span_name="ab12" />
<table_entry span_name="ab12">Text Value</table_entry>
<spec_span span_start="c2" span_end="c12" span_name="ab17" />
<spec_span span_start="c2" span_end="c12" span_name="ab15" />
<table_entry span_name="ab15">Text Value 2</table_entry>
<table_entry span_name="ab16">Text Value 3</table_entry>
</root>
you can use this stylesheet (which also works with XSLT 2.0):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" indent="yes"/>
<xsl:template match="root">
<xsl:apply-templates select="spec_span[//table_entry/@span_name = @span_name]"/>
</xsl:template>
<xsl:template match="spec_span">
<xsl:variable name="span_name" select="@span_name"/>
<xsl:variable name="colspan"
select="number(substring(@span_end, 2)) - number(substring(@span_start, 2)) + 1"/>
<td colspan="{$colspan}">
<xsl:value-of select="//table_entry[@span_name=$span_name]"/>
</td>
</xsl:template>
</xsl:stylesheet>
which will deal with any spec_span
/table_entry
pairs (including the example you posted). It will generate two td
s for the example above since only two pairs match:
<td colspan="8">Text Value</td>
<td colspan="11">Text Value 2</td>
<table_entry>
does not match the closing tag</entry>
. – michael.hor257k