我有一个看起来像这样的xml文档:
<units>
<unit>
<year></year>
<month></month>
<qty></qty>
</unit>
</units>
我想在html中创建此数据的交叉表视图,每行由一年表示,每列由一个月表示,每个值包含特定年/月的数量之和。有点像这样:
Jan Feb Mar Apr.... etc
2010 345 0 12 0
2011 1 23 344 0
2012 99 1 23 0.... etc
我的主要问题是:xslt甚至可以使用交叉表吗?
我的后续问题是,你可以指出一个xslt新手,比如我自己,正确的方向开始尝试使这项工作吗?
示例数据:
<units>
<unit>
<year>2010</year>
<month>9</month>
<qty>13320</qty>
</unit>
<unit>
<year>2010</year>
<month>9</month>
<qty>2445</qty>
</unit>
<unit>
<year>2010</year>
<month>10</month>
<qty>8949</qty>
</unit>
<unit>
<year>2010</year>
<month>10</month>
<qty>13650</qty>
</unit>
<unit>
<year>2010</year>
<month>11</month>
<qty>4091</qty>
</unit>
<unit>
<year>2010</year>
<month>11</month>
<qty>6600</qty>
</unit>
<unit>
<year>2010</year>
<month>12</month>
<qty>686</qty>
</unit>
<unit>
<year>2010</year>
<month>12</month>
<qty>678</qty>
</unit>
<unit>
<year>2011</year>
<month>1</month>
<qty>1234</qty>
</unit>
<unit>
<year>2011</year>
<month>1</month>
<qty>12345</qty>
</unit>
<unit>
<year>2011</year>
<month>2</month>
<qty>4500</qty>
</unit>
<unit>
<year>2011</year>
<month>2</month>
<qty>999</qty>
</unit>
<unit>
<year>2011</year>
<month>3</month>
<qty>166</qty>
</unit>
<unit>
<year>2011</year>
<month>3</month>
<qty>456666</qty>
</unit>
<unit>
<year>2011</year>
<month>4</month>
<qty>41113</qty>
</unit>
<unit>
<year>2011</year>
<month>4</month>
<qty>1150</qty>
</unit>
<unit>
<year>2011</year>
<month>5</month>
<qty>4150</qty>
</unit>
<unit>
<year>2011</year>
<month>5</month>
<qty>491</qty>
</unit>
<unit>
<year>2011</year>
<month>6</month>
<qty>11250</qty>
</unit>
<unit>
<year>2011</year>
<month>6</month>
<qty>3400</qty>
</unit>
<unit>
<year>2011</year>
<month>7</month>
<qty>485</qty>
</unit>
<unit>
<year>2011</year>
<month>7</month>
<qty>90</qty>
</unit>
<unit>
<year>2011</year>
<month>8</month>
<qty>1606</qty>
</unit>
<unit>
<year>2011</year>
<month>8</month>
<qty>202000</qty>
</unit>
<unit>
<year>2011</year>
<month>9</month>
<qty>45333</qty>
</unit>
<unit>
<year>2011</year>
<month>9</month>
<qty>13650</qty>
</unit>
<unit>
<year>2011</year>
<month>10</month>
<qty>4050</qty>
</unit>
<unit>
<year>2011</year>
<month>10</month>
<qty>431</qty>
</unit>
<unit>
<year>2011</year>
<month>11</month>
<qty>45713</qty>
</unit>
<unit>
<year>2011</year>
<month>11</month>
<qty>13690</qty>
</unit>
<unit>
<year>2011</year>
<month>12</month>
<qty>4050</qty>
</unit>
<unit>
<year>2011</year>
<month>12</month>
<qty>431</qty>
</unit>
<unit>
<year>2012</year>
<month>1</month>
<qty>2500</qty>
</unit>
<unit>
<year>2012</year>
<month>1</month>
<qty>34100</qty>
</unit>
<unit>
<year>2012</year>
<month>2</month>
<qty>400</qty>
</unit>
<unit>
<year>2012</year>
<month>2</month>
<qty>99</qty>
</unit>
<unit>
<year>2012</year>
<month>3</month>
<qty>1606</qty>
</unit>
<unit>
<year>2012</year>
<month>3</month>
<qty>202000</qty>
</unit>
<unit>
<year>2012</year>
<month>4</month>
<qty>53773</qty>
</unit>
<unit>
<year>2012</year>
<month>4</month>
<qty>13650</qty>
</unit>
<unit>
<year>2012</year>
<month>5</month>
<qty>4150</qty>
</unit>
<unit>
<year>2012</year>
<month>5</month>
<qty>4231</qty>
</unit>
<unit>
<year>2012</year>
<month>6</month>
<qty>278</qty>
</unit>
<unit>
<year>2012</year>
<month>6</month>
<qty>6100</qty>
</unit>
<unit>
<year>2012</year>
<month>7</month>
<qty>406</qty>
</unit>
<unit>
<year>2012</year>
<month>7</month>
<qty>95</qty>
</unit>
</units>
答案 0 :(得分:2)
这是一个XSLT 1.0解决方案(可能需要一些工作才能使数字正确对齐):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kUnitByY" match="unit" use="year"/>
<xsl:key name="kUnitByYM" match="unit" use="concat(year,'|',month)"/>
<xsl:template match="/*">
<xsl:text> Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec</xsl:text>
<xsl:apply-templates select=
"unit[generate-id()=generate-id(key('kUnitByY',year)[1])]">
<xsl:sort select="year" data-type="number"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="unit">
<xsl:value-of select="concat('
',year,' ')"/>
<xsl:variable name="vCur" select="."/>
<xsl:for-each select="(//node()|//namespace::*)[not(position() >12)]">
<xsl:value-of select=
"sum(key('kUnitByYM', concat($vCur/year,'|',position()))/qty)"/>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
在以下XML文档中应用此转换时(没有提供!!!):
2010 2 3 2010 3 44 2010 9 44 2011 1 五 2011 3 11 2011 6 11 2011 4 15
产生了想要的正确结果:
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
2010 0 3 44 0 0 0 0 0 44 0 0 0
2011 5 0 11 15 0 11 0 0 0 0 0 0
答案 1 :(得分:1)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="row" match="unit" use="year" />
<xsl:template match="/">
<xsl:text> Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
</xsl:text>
<xsl:apply-templates select="*/unit[
generate-id() = generate-id( key('row',year)[1])]">
<xsl:sort select="year" data-type="number" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="unit">
<xsl:variable name="year" select="year" />
<xsl:value-of select="concat($year,' ')" />
<xsl:for-each select="((/)//@*|(/)//node())[position() < 13]">
<xsl:variable name="month-num" select="position()" />
<xsl:variable name="sum" select="sum(/*/unit[year=$year][month=$month-num]/qty)" />
<xsl:value-of select="concat(substring(' ',1,3 - string-length($sum)),$sum,' ')" />
</xsl:for-each>
<xsl:value-of select="'
'" />
</xsl:template>
</xsl:stylesheet>
...会接受这样的输入......
<units>
<unit>
<year>2010</year>
<month>2</month>
<qty>3</qty>
</unit>
<unit>
<year>2010</year>
<month>3</month>
<qty>44</qty>
</unit>
<unit>
<year>2011</year>
<month>1</month>
<qty>5</qty>
</unit>
<unit>
<year>2011</year>
<month>3</month>
<qty>11</qty>
</unit>
<unit>
<year>2011</year>
<month>4</month>
<qty>15</qty>
</unit>
</units>
...并生成这样的文字......
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
2010 0 3 44 0 0 0 0 0 0 0 0 0
2011 5 0 11 15 0 0 0 0 0 0 0 0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
<xsl:for-each-group select="*/unit" group-by="year">
<xsl:sort select="year" data-type="number" />
<xsl:value-of select="concat(current-grouping-key(),' ')" />
<xsl:value-of select="
(string-join(
for $month-num in 1 to 12 return
for $sum in sum(current-group()/qty) return
concat(substring(' ',1,3 - string-length($sum)),$sum),
' '), '
')" />
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
Dimitre建议添加线路终端校正。
删除输出中的前导零,但保留列对齐。
答案 2 :(得分:0)
您可以使用Muenchian Method