如何总结子文档属性

时间:2012-05-01 10:51:29

标签: xslt sum

有清单

<items>
<item parentid='1'>
<amount>3</amount>
</item>
<item parentid='2'>
<amount>1</amount>
</item>
</items>

和文件:

<udata id='1'>
<price>10</price>
</udata>
<udata id='1'>
<price>20</price>
</udata>

如何总结价格的所有文件? 总结一下,我用了:

<xsl:value-of select="sum(items/item/amount)"/>

我会用:

<xsl:apply-templates select="udata/items/item" mode='price2' />

    <xsl:template mode='price2' match='item'>
        <xsl:apply-templates select="document(concat('upage://', page/@parentId))" mode='price'>
            <xsl:with-param select='amount' name='count'/>
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template mode='price' match='/'>
        <xsl:param name='count'/>
        <xsl:value-of select="$count * /udata/page/properties/group[@name='price_prop']/property[@name='price']/value"/>
    </xsl:template>

结果我有:

3020

我需要50.怎么做?

2 个答案:

答案 0 :(得分:1)

这是一个假设XSLT 2.0的示例(例如,尽可能使用Saxon 9或AltovaXML):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">

  <xsl:param name="data-url" select="'test2012050103.xml'"/>
  <xsl:variable name="data-doc" select="document($data-url)"/>

  <xsl:key name="k1" match="udata" use="@id"/>

  <xsl:template match="items">
    <xsl:value-of select="sum(for $item in item return $item/amount * key('k1', $item/@parentid, $data-doc)/price)"/>
  </xsl:template>

</xsl:stylesheet>

示例文档

<items>
<item parentid='1'>
<amount>3</amount>
</item>
<item parentid='2'>
<amount>1</amount>
</item>
</items>

<root>
<udata id='1'>
<price>10</price>
</udata>
<udata id='2'>
<price>20</price>
</udata>
</root>

输出为50

[edit]这是一个XSLT 1.0样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

  <xsl:param name="data-url" select="'test2012050103.xml'"/>
  <xsl:variable name="data-doc" select="document($data-url)"/>

  <xsl:key name="k1" match="udata" use="@id"/>

  <xsl:template match="items">
    <xsl:call-template name="sum">
      <xsl:with-param name="items" select="item"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="sum">
    <xsl:param name="items" select="/.."/>
    <xsl:param name="total" select="0"/>
    <xsl:choose>
      <xsl:when test="not($items)">
        <xsl:value-of select="$total"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:variable name="price">
          <xsl:for-each select="$data-doc">
            <xsl:value-of select="$items[1]/amount * key('k1', $items[1]/@parentid)/price"/>
          </xsl:for-each>
        </xsl:variable>
        <xsl:call-template name="sum">
          <xsl:with-param name="items" select="$items[position() > 1]"/>
          <xsl:with-param name="total" select="$total + $price"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>


</xsl:stylesheet>

答案 1 :(得分:0)

这是一个较短的解决方案

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:variable name="vPrices" select=
   "document('file:///c:/temp/delete/priceData.xml')/*/*"/>

 <xsl:template match="/*">
  <xsl:apply-templates select="item[1]"/>
 </xsl:template>

 <xsl:template match="item" name="sumProducts">
  <xsl:param name="pAccum" select="0"/>

     <xsl:variable name="vNewAccum" select=
      "$pAccum +amount * $vPrices[@id = current()/@parentid]/price"/>

      <xsl:if test="not(following-sibling::*)">
       <xsl:value-of select="$vNewAccum"/>
      </xsl:if>
      <xsl:apply-templates select="following-sibling::*">
        <xsl:with-param name="pAccum" select="$vNewAccum"/>
      </xsl:apply-templates>
 </xsl:template>
</xsl:stylesheet>

应用于以下XML文档时:

<items>
    <item parentid='1'>
        <amount>3</amount>
    </item>
    <item parentid='2'>
        <amount>1</amount>
    </item>
</items>

并且文件c:\temp\delete\priceData.xml包含:

<root>
    <udata id='1'>
        <price>10</price>
    </udata>
    <udata id='2'>
        <price>20</price>
    </udata>
</root>

然后生成想要的正确结果:

50