我有一个xml文件,我需要根据标记值对计数值求和 现在标签值的范围是0到800.我需要根据标签系列计算计数值的总和,如系列上的0-100,此系列的一个计数总和,然后是100 -200,依此类推。
输入XML文件:
<?xml version='1.0' encoding='utf8'?>
<marcstats>
<datafields>
<field count="3519" tag="035">
<subfields>
<subfield code="a" count="3519" />
</subfields>
</field>
<field count="4123" tag="100">
<subfields>
<subfield code="a" count="4123" position="" />
</subfields>
</field>
<field count="3515" tag="101">
<subfields>
<subfield code="4" count="" position="" />
</subfields>
</field>
<field count="4123" tag="200">
<subfields>
<subfield code="a" count="4123" />
<subfield code="e" count="57" />
</subfields>
</field>
<field count="181" tag="215">
<subfields>
<subfield code="a" count="181" />
</subfields>
</field>
<field count="320" tag="300">
<subfields>
<subfield code="a" count="320" />
</subfields>
</field>
<field count="2896" tag="330">
<subfields>
<subfield code="a" count="2896" />
</subfields>
</field>
到目前为止我写的XSL:
<xsl:key name="tag" match="//field" use="@tag"/>
<xsl:template match="/">
<chart>
<categories>
<xsl:call-template name="process-category">
</xsl:call-template>
</categories>
<xsl:call-template name="process-series">
<xsl:with-param name="max">
<xsl:for-each select="//field/@tag">
<xsl:sort select="." data-type="number"
order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:with-param>
</xsl:call-template>
</chart>
</xsl:template>
<xsl:template name="process-category">
<item>100</item>
<item>200</item>
<item>300</item>
<item>400</item>
</xsl:template>
<xsl:template name="process-series">
<xsl:param name="max"/>
<xsl:if test="//field[$endCount < $max]">
<series>
<name>0xx</name>
<data>
<point><xsl:value-of
select="sum(//field
[@tag > $startCount
and @tag < $endCount]/@count)"/></point>
</data>
</series>
</xsl:if>
</xsl:template>
但它只给出了一个系列,如何实现所有系列?
答案 0 :(得分:0)
我刚刚创建了一个执行计数的简单模板:
<xsl:template name="sum">
<xsl:param name="from"/>
<xsl:param name="to"/>
<xsl:value-of select="sum(//field[@tag >= $from and @tag < $to]/@count)"/>
</xsl:template>
在这里,您可以看到整个XSLT输出@tag 0到100和100到200的字段总和:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:output indent="yes"></xsl:output>
<xsl:template match="/">
<sum_0_100>
<xsl:call-template name="sum">
<xsl:with-param name="from" select="0"/>
<xsl:with-param name="to" select="100"/>
</xsl:call-template>
</sum_0_100>
<sum_100_200>
<xsl:call-template name="sum">
<xsl:with-param name="from" select="100"/>
<xsl:with-param name="to" select="200"/>
</xsl:call-template>
</sum_100_200>
</xsl:template>
<xsl:template name="sum">
<xsl:param name="from"/>
<xsl:param name="to"/>
<xsl:value-of select="sum(//field[@tag >= $from and @tag < $to]/@count)"/>
</xsl:template>
</xsl:stylesheet>
这为您提供了此输出:
<sum_0_100>3519</sum_0_100>
<sum_100_200>7638</sum_100_200>
现在,您可以在XSLT中使用它,并创建适当的元素
答案 1 :(得分:0)
怎么样:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="field-by-cat" match="field" use="@tag - @tag mod 100"/>
<xsl:variable name="max">
<xsl:for-each select="/marcstats/datafields/field">
<xsl:sort select="@tag" data-type="number" order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="@tag"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:template match="/">
<data>
<xsl:call-template name="summarize"/>
</data>
</xsl:template>
<xsl:template name="summarize">
<xsl:param name="from" select="0"/>
<xsl:param name="to" select="$from + 100"/>
<point from="{$from}" to="{$to}">
<xsl:value-of select="sum(key('field-by-cat', $from)/@count)"/>
</point>
<xsl:if test="$max > $to">
<xsl:call-template name="summarize">
<xsl:with-param name="from" select="$to"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
当应用于您的输入(校正良好格式)时,结果为:
<?xml version="1.0" encoding="UTF-8"?>
<data>
<point from="0" to="100">3519</point>
<point from="100" to="200">7638</point>
<point from="200" to="300">4304</point>
<point from="300" to="400">3216</point>
</data>