我正在尝试将XML文件转换为另一个XML文件,根据标记值

时间:2015-07-26 19:30:22

标签: xml sorting xslt grouping

我想转换以下XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<dataroot> 
  <Op>
    <Where>AIX</Where>
    <Amount>24</Amount>
  </Op>
  <Op>
    <Where>LILLE</Where>
    <Amount>10</Amount>
  </Op>
  <Op>
    <Where>LILLE</Where>
    <Amount>18</Amount>
  </Op>
  <Op>
    <Where>AIX</Where>
    <Amount>20</Amount>
  </Op>
  <Op>
    <Where>LILLE</Where>
    <Amount>12</Amount>
   </Op>
</dataroot>

<?xml version="1.0" encoding="UTF-8"?>
<Document> 
  <Recap>
   <Nop>5</Nop>
    <TotAmount>84</TotAmount>
  </Recap>
  <Location>
    <Where>AIX</Where>
    <Nop>2</Nop>
    <LocAmount>44</LocAmount>
    <Ops>
      <Amount>24</Amount>
      <Amount>20</Amount>
    </Ops>
  </Location>
  <Location> 
    <Where>LILLE</Where>
    <Nop>3</Nop>
    <LocAmount>40</LocAmount>
    <Ops>
       <Amount>10</Amount>
       <Amount>18</Amount>
       <Amount>12</Amount>
    </ops>
  </Location>
</Document>

这是将针对给定位置执行的操作组合在一起,计算其数量和每个位置的操作总量。我尝试使用排序但没有成功。

我是新手,我不知道该怎么做。

按照michael.hor257k的建议,我尝试使用以下xsl代码创建分组,但我仍然无法为每个位置计算操作计数(Nop)和LocAmount:

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

  <xsl:output encoding="UTF-8" method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="Ops-by-location" match="Op" use="Where" />

  <xsl:template match="/">
    <Document> 
      <Recap>
        <Nop><xsl:value-of select="count(//Amount)"/></Nop>
        <TotAmount><xsl:value-of select="sum(//Amount)"/></TotAmount>
      </Recap>
      <xsl:apply-templates/> 
    </Document>  
  </xsl:template>

  <xsl:template match="/dataroot">
    <xsl:apply-templates select="Op[generate-id(.) = generate-id(key('Ops-by-location', Where)[1])]"/>
  </xsl:template>

  <xsl:template match="Op">
    <Where>
      <xsl:value-of select="Where" />
      <Nop>???</Nop>
      <TotAmount>???</TotAmount>
      <xsl:for-each select="key('Ops-by-location', Where)">
        <Amount> <xsl:value-of select="Amount" /></Amount>
      </xsl:for-each>
    </Where>
  </xsl:template>
</xsl:stylesheet>

3 个答案:

答案 0 :(得分:1)

  

我仍无法计算操作次数(Nop)和LocAmount   对于每个地点

尝试:

        <Nop>
            <xsl:value-of select="count(key('Ops-by-location', Where))"/>
        </Nop>
        <TotAmount>
            <xsl:value-of select="sum(key('Ops-by-location', Where)/Amount)"/>
        </TotAmount>

或者,效率更高:

<xsl:template match="Op">
    <xsl:variable name="local-ops" select="key('Ops-by-location', Where)"/>
    <Location>
        <xsl:copy-of select="Where"/>
        <Nop>
            <xsl:value-of select="count($local-ops)"/>
        </Nop>
        <TotAmount>
            <xsl:value-of select="sum($local-ops/Amount)"/>
        </TotAmount>
        <xsl:copy-of select="$local-ops/Amount"/>
    </Location>
</xsl:template>

答案 1 :(得分:0)

试试这个

sudo make install

答案 2 :(得分:0)

这是使用Muenchian方法的XSLT 1.0解决方案:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" />

<xsl:key name="Where" match="/dataroot/Op/Where" use="text()" />

<xsl:template match="/">
  <xsl:element name="Document">
    <xsl:element name="Recap">
      <xsl:for-each select="//dataroot">
    <Nop><xsl:value-of select="count(*)"/></Nop>
        <TotAmount><xsl:value-of select="sum(//Amount)"/></TotAmount>
      </xsl:for-each>
    </xsl:element>

   <xsl:for-each select="/dataroot/Op/Where[generate-id()
                         = generate-id(key('Where',text())[1])]">
    <xsl:element name="Location">       

      <Where><xsl:value-of select="."/></Where>             
      <Nop><xsl:value-of select="count(key('Where',text()))"/></Nop>
      <LocAmount><xsl:value-of select="sum(key('Where',text())/../Amount)"/></LocAmount>

    <xsl:element name="Ops">
       <xsl:copy-of select="key('Where',text())/../Amount"/>              
    </xsl:element>

    </xsl:element>      
   </xsl:for-each>      

  </xsl:element>  
</xsl:template>

</xsl:stylesheet>