Summing related values

2019-09-22 18:09发布

I have this .xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<output>
    <orders>
        <order>
            <id>1</id>
            <number>10002</number>
            <type>Loading</type>
            <date>2013-01-01T02:30:00</date>
        </order>
        <order>
            <id>2</id>
            <number>10003</number>
            <type>Loading</type>
            <date>2013-01-01T010:30:00</date>
        </order>
        <order>
            <id>3</id>
            <number>10004</number>
            <type>Loaded</type>
            <date>2013-01-01T12:30:00</date>
        </order>
    </orders>
    <quantities>
        <quantity>
            <id_order>1</id_order>
            <unit>KG</unit>
            <value>1000</value>
        </quantity>
        <quantity>
            <id_order>1</id_order>
            <unit>PAL</unit>
            <value>3</value>
        </quantity>
        <quantity>
            <id_order>1</id_order>
            <unit>M3</unit>
            <value>1.5</value>
        </quantity>
        <quantity>
            <id_order>2</id_order>
            <unit>KG</unit>
            <value>2000</value>
        </quantity>
        <quantity>
            <id_order>2</id_order>
            <unit>PAL</unit>
            <value>4</value>
        </quantity>
        <quantity>
            <id_order>3</id_order>
            <unit>KG</unit>
            <value>5000</value> 
        </quantity>
    </quantities>
</output>

and the desired transformation is something like

<output>
    <amount>KG</amount>
        <total> "sum of all KG elements" </total>
    <amount>PAL</amount>
        <total> "sum of all PAL elements" </total>
    <amount>M3</amount>
        <total> "sum of all M3 elements" </total>
</output>

I've tried something like

<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:template match="/">
<output>
        <xsl:for-each select="output/quantities/quantity"> 
            <amount>
                <xsl:value-of select="unit"/>

                <xsl:for-each select="output/quantities/quantity/value">
                        <xsl:value-of select="sum(output/quantities/quantity/value)"/>   

                </xsl:for-each> 
            </amount>    
        </xsl:for-each>
    </output>
</xsl:template>

</xsl:stylesheet>

but I don't get the sum of values and the output is broken like this

<output>
  <amount>KG<total/></amount>
  <amount>PAL<total/></amount>
  <amount>M3<total/></amount>
  <amount>KG<total/></amount>
  <amount>PAL<total/></amount>
  <amount>KG<total/></amount>
</output>

I've tried few other workarounds but none worked to my desired output. If anyone could suggest anything or help in any way I would appreciate it.

Now Im trying to add another node, in the first xml, called after which should basically have value of copied value stripped to show only after hours (hh:mm:ss). I've managed to create a copy of the original xml and add the extra tag, but I'm not sure on how to extract the hour data and show in inside tags.

<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:strip-space elements="*"/>


   <xsl:template match="@* | node()">
      <xsl:copy>
         <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="date">
      <xsl:copy-of select="."/>
      <hour>
<xsl:comment> <xsl:copy-of select="substring(output/orders/order/date,11)"/> </xsl:comment>
       </hour>
   </xsl:template>

</xsl:stylesheet>

1条回答
手持菜刀,她持情操
2楼-- · 2019-09-22 18:53

Try it this way:

<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="qty" match="quantity" use="unit"/>  

<xsl:template match="/">
    <output>
        <amount>KG</amount>
        <total><xsl:value-of select="sum(key('qty', 'KG')/value)"/></total>
        <amount>PAL</amount>
        <total><xsl:value-of select="sum(key('qty', 'PAL')/value)"/></total>
        <amount>M3</amount>
        <total><xsl:value-of select="sum(key('qty', 'M3')/value)"/></total>
    </output>
</xsl:template>

</xsl:stylesheet>

Note that this is not the best output format you could choose; ideally, the unit and the amount would be contained by a common element, not just adjacent siblings.

查看更多
登录 后发表回答