XML,XPATH添加值

时间:2011-01-14 08:28:04

标签: java xml xpath

我有XML文件,其中包含具有以下结构的记录:

<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>

每个文件都有许多付款类型的记录,我希望最终的xml包含一个付款 通过为每个不同的代码值添加所有金额值来记录 上面的xml的结果是

<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>

我认为XPath可以用于此,但我以前从未使用过它,有人可以给我看一些Java(或其他)代码吗?

1 个答案:

答案 0 :(得分:1)

XPath的好例子:http://www.w3schools.com/XPath/xpath_examples.asp考虑​​到你的例子,你很容易就可以得到它。示例基于JavaScript 潜入你的问题,我认为你需要的是xslt转换,根据给定创建另一个xml文件。 Here是类似的例子,非常简化。要计算<gr>金额摘要,您需要执行以下操作:

sum(//gr/@amount)

<强>更新 嗯,刚决定玩一下。我做了什么:

1)以Eclipse IDE为例 2)用你的xml文件创建项目
3)创建类似的xsl文件:

<?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)右键单击该xsl文件并执行“Run As ... / XSL Transformation”
5)从工作区中选择你的xml文件,你得到结果:

<?xml version="1.0" encoding="UTF-8"?><totalpayment>2126.5099999999998</totalpayment>
  • 在内部标签中你得到总金额(是的,不精确,只需阅读sum和xslt以获得如何改进计算以获得精确的总和)。

我不知道结果结构应该是什么,所以只创建了一个如何获取任何内容的示例,现在您可以使用它了。

小解释:     sum(//@amount) - 它采用具有属性数量的所有标签并计算金额值的总和

UPDATE2,根据输入/输出示例

尝试这个XSLT转换:

<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>

我刚刚用你给出的xml执行了这个xsl,我得到了你需要的相同结果:

<?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>

除了价值<gr code="1" amount="2512.00"/> - 我不知道为什么2512.00。

我不知道你的xslt是否已经准备就绪,或者它不是那么普遍,但我希望这是一个好的开始!