I have the following XML:
<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>
I want to ultimately put them into an HTML table (the x
and y
are coordinates of cells in that table), and to make it easier I want to put the items into rows, like this:
<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>
But the only transform I can come up with not only doesn't work, but also doesn't allow me to annotate the rows with row number.
<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>
How can I accomplish this?
Your posted XSLT isn't valid - a proper processor won't let you start and end tags like that in a way that could end up being invalid XML.
You need to group these - if you're using XSLT 1.0 you can use Muenchian grouping like so, although I'm not quite sure how to make sense of your expected output given your input:
results in:
If you're using XSLT 2.0, you could do something like
<xsl:for-each-group>
, see How to use for each group in XSL for more information.