XML, XPATH adding values
i have XML files which contain records with the following stru开发者_运维百科cture:
<xml>
<payment contractType="1">
<income type="0">
<gr code="1" amount="1506.00"/>
<gr code="4" amount="35.00"/>
<gr code="10" amount="288.14"/>
<de code="3011300" amount="138.72"/>
<de code="3081100" amount="48"/>
<de code="3082400" amount="110"/>
</income>
<netAmount1 value="765.00"/>
<netAmount2 value="765.00"/>
</payment>
<payment contractType="1">
<income type="0">
<gr code="1" amount="506.00"/>
<gr code="4" amount="35.00"/>
<gr code="10" amount="0"/>
<de code="3011300" amount="1.28"/>
<de code="3081100" amount="48"/>
<de code="3082400" amount="120"/>
</income>
<netAmount1 value="635.00"/>
<netAmount2 value="635.00"/>
</payment>
</xml>
each file has many records of type payment and i want the final xml to contain one payment record by adding all the amount values for every differrent code value the result of the xml above is
<xml>
<payment contractType="1">
<income type="0">
<gr code="1" amount="2512.00"/>
<gr code="4" amount="70.00"/>
<gr code="10" amount="288.14"/>
<de code="3011300" amount="140"/>
<de code="3081100" amount="96"/>
<de code="3082400" amount="230"/>
</income>
<netAmount1 value="1400.00"/>
<netAmount2 value="1400.00"/>
</payment>
</xml>
I think XPath can be used for this, but I never used it before , could someone show me some Java (or else) code for this?
Good examples of XPath: http://www.w3schools.com/XPath/xpath_examples.asp taking into account your example, you will easy get it based on that. Examples are based on JavaScript
And diving into your propblem, I think what you need is xslt transformation, create another xml file based on given. Here is similar example, quite simplified. To calculate summary of <gr>
amount you need to perform something like:
sum(//gr/@amount)
UPDATE: Well, just decided to play a bit with that. What I did:
1) Take Eclipse IDE
2) create project with your xml file
3) create xsl file like that:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<totalpayment>
<xsl:value-of select='sum(//@amount)'/>
</totalpayment>
</xsl:template>
</xsl:stylesheet>
4) Right click on that xsl file and execute "Run As.../XSL Transformation"
5) select your xml file from workspace and you get the result:
<?xml version="1.0" encoding="UTF-8"?><totalpayment>2126.5099999999998</totalpayment>
- inside tag you get total amount (yeah, not precise, just read about sum and xslt to get how to improve calculating to get exact sum).
I don't know what's the result structure should be, so just created an example how to get anything, now you can play with that.
Little explanation:
sum(//@amount)
- it takes all tags with attribute amount and calculates sum of amount values
UPDATE2, according to input/output example
Try this XSLT transformation out:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:key name="names" match="//*" use="local-name(.)" />
<xsl:template match="/">
<payment contractType="1">
<income type="0">
<xsl:for-each select="//@code[not(.=preceding::*//@code)]">
<xsl:variable name="tagname">
<xsl:value-of select="name(//*[@code=current()])" />
</xsl:variable>
<xsl:element name="{$tagname}">
<xsl:attribute name="code">
<xsl:value-of select="current()" />
</xsl:attribute>
<xsl:attribute name="amount">
<xsl:value-of select="sum(//*[@code=current()]/@amount)" /><br />
</xsl:attribute>
</xsl:element>
</xsl:for-each>
<xsl:for-each select="//*[generate-id(.) = generate-id(key('names', local-name(.))) and starts-with(name(),'netAmount')]">
<xsl:variable name="tagname">
<xsl:value-of select="name()" />
</xsl:variable>
<xsl:element name="{name()}">
<xsl:attribute name="value">
<xsl:value-of select="sum(//*[name()=$tagname]/@value)"></xsl:value-of>
</xsl:attribute>
</xsl:element>
</xsl:for-each>
</income>
</payment>
</xsl:template>
</xsl:stylesheet>
I've just executed this xsl with xml you had given, and I've got the same result you need:
<?xml version="1.0" encoding="UTF-8"?>
<payment contractType="1">
<income type="0">
<gr code="1" amount="2012"/>
<gr code="4" amount="70"/>
<gr code="10" amount="288.14"/>
<de code="3011300" amount="140"/>
<de code="3081100" amount="96"/>
<de code="3082400" amount="230"/>
<netAmount1 value="1400"/>
<netAmount2 value="1400"/>
</income>
</payment>
Except for value <gr code="1" amount="2512.00"/>
- I don't know why 2512.00.
I don't know if that xslt is ready to use by you, or it is not that general, but I hope this is good start!
精彩评论