2017-02-14 10 views
1

У меня есть следующий XML:Как отсортировать список элементов XML в строках для таблицы HTML?

<items> 
    <item x="1" y="3"/> 
    <item x="2" y="4"/> 
    <item x="3" y="4"/> 
    <item x="4" y="2"/> 
    <item x="5" y="1"/> 
</items> 

Я хочу, чтобы в конечном итоге положить их в HTML-таблицы (в x и y являются координаты ячеек в этой таблице), и, чтобы сделать его проще, я хочу, чтобы поместить элементы в ряды, как это:

<items> 
    <row y="1"> 
    <item x="1" y="1"/> 
    </row> 
    <row y="2"> 
    <item x="2" y="2"/> 
    </row> 
    <row y="3"> 
    <item x="5" y="3"/> 
    </row> 
    <row y="4"> 
    <item x="3" y="4"/> 
    <item x="4" y="4"/> 
    </row> 
</items> 

но единственное преобразование я могу придумать не только не работает, но и не позволяет мне аннотировать строки с номером строки.

<xsl:template match="/items"> 
    <items> 
    <row> 
     <xsl:for-each select="item"> 
     <xsl:sort select="@y"/> 
     <xsl:sort select="@x"/> 

     <xsl:if test="preceding-sibling::item[1]/@y != @y"> 
      <xsl:text>"</row>"</xsl:text> 
      <xsl:text>"<row>"</xsl:text> 
     </xsl:if> 
     <xsl:copy-of select="."/> 
     </xsl:for-each> 
    </row> 
    </items> 
</xsl:template> 

Как это сделать?

+0

XSLT 1.0 или 2.0? –

+0

Извините, XSLT 1.0. Я добавлю этот тег. – Fylke

ответ

2

Ваш опубликованный XSLT недействителен - надлежащий процессор не позволит вам запускать и заканчивать теги таким образом, что может оказаться недопустимым XML.

Вам нужно сгруппировать эти - если вы используете XSLT 1.0 вы можете использовать Muenchian группировки, как это так, хотя я не совсем уверен, как сделать смысл вашего ожидаемого результата учитывая ваш вклад:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="html" omit-xml-declaration="yes" indent="yes" /> 
    <xsl:key name="items-by-y" match="item" use="@y" /> 
    <xsl:template match="/items"> 
    <items> 
     <xsl:for-each select="item[count(. | key('items-by-y', @y)[1]) =1]"> 
     <xsl:sort select="@y" /> 
     <xsl:sort select="@x" /> 
     <row y="{@y}"> 
      <xsl:for-each select="key('items-by-y', @y)"> 
      <xsl:copy-of select="." /> 
      </xsl:for-each> 
     </row> 
     </xsl:for-each> 
    </items> 
    </xsl:template> 
</xsl:stylesheet> 

результаты в:

<items> 
    <row y="1"> 
     <item x="5" y="1"/> 
    </row> 
    <row y="2"> 
     <item x="4" y="2"/> 
    </row> 
    <row y="3"> 
     <item x="1" y="3"/> 
    </row> 
    <row y="4"> 
     <item x="2" y="4"/> 
     <item x="3" y="4"/> 
    </row> 
</items> 

Если вы используете XSLT 2.0, вы могли бы сделать что-то вроде <xsl:for-each-group> см How to use for each group in XSL для получения дополнительной информации.

+0

Прохладный спасибо! В каждом элементе есть больше элементов, но я их оставил, чтобы просто включить наиболее релевантную информацию. – Fylke

+0

Я не понимаю, как работает первый для каждого. Вы просматриваете все y-элементы, берете первый и подсчитываете результат - или текущий элемент (если он пуст?). Не могли бы вы объяснить это? – Fylke

+0

Взгляните на https://en.wikipedia.org/wiki/XSLT/Muenchian_grouping или google Muenchian grouping. Первый в основном использует «ключ», чтобы гарантировать, что вы выполняете итерацию только по отдельным y-элементам. –

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