2012-10-03 45 views
2

我想對具有城市人口的每個國家的人口總和進行總結。鑑於下面的示例代碼,它不起作用。你可以請幫我在做這個工作如何通過使用XSLT 1.0做羣體總和

輸入是

<cities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org file:/D:/Oracle/JDev11116/jdeveloper/jdev/MyWork/TelenorFTPIssueApp/XSLTGroupProj/MySchema.xsd" xmlns="http://www.example.org"> 
    <city name="Milano" country="Italia"  pop="5"/> 
    <city name="Paris" country="France"  pop="7"/> 
    <city name="München" country="Deutschland" pop="4"/> 
    <city name="Lyon" country="France"  pop="2"/> 
    <city name="Venezia" country="Italia"  pop="1"/> 
</cities> 

,並期望輸出

<?xml version = '1.0' encoding = 'UTF-8'?> 
<ns1:Out xmlns:ns1="http://www.example.org" > 
    <ns1:line> 
     <ns1:position>1</ns1:position> 
     <ns1:country>Italia</ns1:country> 
     <ns1:city>Milano, Venezia</ns1:city> 
     <ns1:population>6</ns1:population> 
    </ns1:line> 
    <ns1:line> 
     <ns1:position>2</ns1:position> 
     <ns1:country>France</ns1:country> 
     <ns1:city>Paris, Lyon</ns1:city> 
     <ns1:population>9</ns1:population> 
    </ns1:line> 
    <ns1:line> 
     <ns1:position>3</ns1:position> 
     <ns1:country>Deutschland</ns1:country> 
     <ns1:city>München</ns1:city> 
     <ns1:population>4</ns1:population> 
    </ns1:line> 
</ns1:Out> 

的XSL,我在工作是

<xsl:stylesheet version="1.0" xmlns:ns1="http://www.example.org" > 
    <xsl:key match="ns1:city" name="count_name" use="@country"/>   
    <xsl:template match="/"> 
    <ns1:Out> 
    <xsl:for-each select="ns1:cities/ns1:city[count(. | key('count_name', @country)[1]) = 1]" > 
    <ns1:line> 
     <ns1:position> 
      <xsl:value-of select="position()"/> 
     </ns1:position> 
     <ns1:country> 
      <xsl:value-of select="@country"/> 
     </ns1:country> 
     <ns1:city>   
      <xsl:for-each select="key('count_name', @country)"> 
        <xsl:value-of select="key('count_name',@city)" separator=", "/> 
      </xsl:for-each> 
     </ns1:city> 
     <ns1:population> 
      <xsl:for-each select="key('count_name', @country)"> 
       <xsl:value-of select="sum(key('count_name', @population))" /> 
      </xsl:for-each> 
     </ns1:population> 
    </ns1:line> 
    </xsl:for-each> 
    </ns1:Out> 
    </xsl:template> 
</xsl:stylesheet> 

回答

0

一個解決方案,是稍微更具聲明

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ns1="http://www.example.org"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:key name="kCityByCountry" match="ns1:city" use="@country"/> 

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

<xsl:template match="/*"> 
    <ns1:Out xmlns:ns1="http://www.example.org"> 
    <xsl:apply-templates/> 
    </ns1:Out> 
</xsl:template> 

<xsl:template match= 
    "ns1:city[generate-id()=generate-id(key('kCityByCountry',@country)[1])]"> 
    <ns1:line> 
    <ns1:position> 
     <xsl:number count="ns1:city 
      [generate-id()=generate-id(key('kCityByCountry',@country)[1])]"/> 
    </ns1:position> 
    <ns1:country><xsl:value-of select="@country"/></ns1:country> 
    <ns1:city> 
    <xsl:for-each select="key('kCityByCountry',@country)"> 
     <xsl:if test="not(position()=1)">, </xsl:if> 
     <xsl:value-of select="@name"/> 
    </xsl:for-each> 
    </ns1:city> 
    <ns1:population><xsl:value-of select= 
       "sum(key('kCityByCountry',@country)/@pop)"/></ns1:population> 
    </ns1:line> 
</xsl:template> 
<xsl:template match="ns1:city"/> 
</xsl:stylesheet> 

當這個變換所提供的XML文檔應用:

<cities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.example.org file:/D:/Oracle/JDev11116/jdeveloper/jdev/MyWork/TelenorFTPIssueApp/XSLTGroupProj/MySchema.xsd" 
xmlns="http://www.example.org"> 
    <city name="Milano" country="Italia"  pop="5"/> 
    <city name="Paris" country="France"  pop="7"/> 
    <city name="München" country="Deutschland" pop="4"/> 
    <city name="Lyon" country="France"  pop="2"/> 
    <city name="Venezia" country="Italia"  pop="1"/> 
</cities> 

想要的,正確的結果產生:

<ns1:Out xmlns:ns1="http://www.example.org"> 
    <ns1:line> 
     <ns1:position>1</ns1:position> 
     <ns1:country>Italia</ns1:country> 
     <ns1:city>Milano, Venezia</ns1:city> 
     <ns1:population>6</ns1:population> 
    </ns1:line> 
    <ns1:line> 
     <ns1:position>2</ns1:position> 
     <ns1:country>France</ns1:country> 
     <ns1:city>Paris, Lyon</ns1:city> 
     <ns1:population>9</ns1:population> 
    </ns1:line> 
    <ns1:line> 
     <ns1:position>3</ns1:position> 
     <ns1:country>Deutschland</ns1:country> 
     <ns1:city>München</ns1:city> 
     <ns1:population>4</ns1:population> 
    </ns1:line> 
</ns1:Out> 
0

用途:

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

    <xsl:key name="k" match="ns1:city" use="@country"/> 

    <xsl:template match="ns1:cities"> 
    <ns1:Out> 
     <xsl:apply-templates 
     select="ns1:city[generate-id() = generate-id(key('k', @country))]"/> 
    </ns1:Out> 
    </xsl:template> 

    <xsl:template match="ns1:city"> 
    <ns1:line> 
     <ns1:position> 
     <xsl:value-of select="position()"/> 
     </ns1:position> 
     <ns1:country> 
     <xsl:value-of select="@country"/> 
     </ns1:country> 
     <ns1:city> 
     <xsl:for-each select="key('k', @country)"> 
      <xsl:value-of select="@name"/> 
      <xsl:if test="position() != last()"> 
      <xsl:text>, </xsl:text> 
      </xsl:if> 
     </xsl:for-each> 
     </ns1:city> 
     <ns1:population> 
     <xsl:value-of select="sum(key('k', @country)/@pop)"/> 
     </ns1:population> 
    </ns1:line> 
    </xsl:template> 

</xsl:stylesheet> 

輸出:

<ns1:Out xmlns:ns1="http://www.example.org"> 
    <ns1:line> 
    <ns1:position>1</ns1:position> 
    <ns1:country>Italia</ns1:country> 
    <ns1:city>Milano, Venezia</ns1:city> 
    <ns1:population>6</ns1:population> 
    </ns1:line> 
    <ns1:line> 
    <ns1:position>2</ns1:position> 
    <ns1:country>France</ns1:country> 
    <ns1:city>Paris, Lyon</ns1:city> 
    <ns1:population>9</ns1:population> 
    </ns1:line> 
    <ns1:line> 
    <ns1:position>3</ns1:position> 
    <ns1:country>Deutschland</ns1:country> 
    <ns1:city>München</ns1:city> 
    <ns1:population>4</ns1:population> 
    </ns1:line> 
</ns1:Out>