2013-03-01 2 views
1

У меня есть XML, похожий наXSLT - Counting атрибуты внутри элемента

<BOXHEAD> 
    <COLHEAD H="1">Item</COLHEAD> 
    <COLHEAD H="2">Cost</COLHEAD> 
    <COLHEAD H="3">Direct</COLHEAD> 
    <COLHEAD H="3">In-Direct</COLHEAD> 
    <COLHEAD H="2">Revenue</COLHEAD> 
    <COLHEAD H="3">1989</COLHEAD> 
    <COLHEAD H="3">1990</COLHEAD> 
</BOXHEAD> 

я пытался что-то похожее на это, чтобы перевести на HTML Colspan:

<xsl:if test="@H=2"> 
    <xsl:variable name="descendants" select="following-sibling::COLHEAD[@H = 3]"/> 
    <xsl:variable name="number_of_columns_under_this" select="count($descendants)"/> 
    <xsl:if test="$number_of_columns_under_this &gt; 1"> 
     <xsl:attribute name="colspan"> 
      <xsl:value-of select="$number_of_columns_under_this"/> 
     </xsl:attribute> 
    </xsl:if> 
</xsl:if> 

Желаемый результат: "стоимость" колонка должна выйти до colspan="2", но, конечно, count() поднимает все четыре из @H="3" в блоке. Я пытаюсь превратить этот древний SGML в таблицу HTML. Нужный из пут похож на это:

<table> 
<tbody> 
<tr> 
    <td colspan="1" rowspan="2">Item</td> 
    <td colspan="2" rowspan="1">Cost</td> 
    <td colspan="2" rowspan="1">Revenue</td> 
</tr> 
<tr> 
    <td>Direct</td> 
    <td>In-Direct</td> 
    <td>1989</td> 
    <td>1990</td> 
</tr> 
</tbody> 
</table> 

Расчет RowSpan и Объединение столбцов, оказывается трудным для меня.

+0

Можете ли вы разместить желаемый выходной XML для ввода этого образца? –

+0

Требование .. похоже, я понимаю, но я не уверен в себе. То, что я понимаю, так .., поскольку вы используете следующий брат, он вернет '4', когда вы встретите' Стоимость ' и он возвращает '2', когда вы сталкиваетесь с' Доход ' –

+1

То, что вы ожидаете от него, возвращается ** - это количество последовательных элементов ** COLHEAD (имеющих атрибут H =" 3 "), следующий за текущим узлом .. это правильно? –

ответ

3

Вы можете использовать трюк, как этот

<xsl:variable name="descendants" 
    select="following-sibling::COLHEAD[@H = 3] 
     [generate-id((preceding-sibling::COLHEAD[@H=2])[last()]) 
     = generate-id(current())]"/> 

Это выбирает все COLHEAD[@H=3] элементов, ближайшего предшествующего-родственный @H=2 это один мы сейчас смотрим.

+0

+1 для точного решения .. –

+0

Wow. Я попробую. Сейчас я все еще пытаюсь понять это. – Paulb

+0

@Paulb 'generate-id' - очень полезная функция, она позволяет вам проверить, выбрали ли два выражения _same node_ (а не только узлы, которые имеют одинаковое строковое значение). Итак, что я делаю здесь: для каждого '@ H = 3' COLHEAD найдите все свои элементы-предшественники[email protected] H = 2', выберите один из тех, который является самым последним в порядке документа, и проверьте, одинаково ли это узел как '@ H = 2', с которого мы начали (используя' current() ', чтобы получить контекстный узел из-за' [] ') –

2

Если вы находитесь в XSLT 2.0, вам, вероятно, следует использовать позиционную группировку для чего-то вроде <xsl:for-each-group group-starting-with="[@H='2']>. Но, не зная точно, какой результат вы хотите, трудно предложить вам более подробную информацию.

+0

Ответ вчера работал на пару прецедентов, затем развалился. Поэтому, возможно, я буду изучать XSLT 2.0 для каждой группы. Я уточнил свой первоначальный вопрос, добавив желаемый результат. Спасибо. – Paulb

Смежные вопросы