2

我想对每个国家/地区的城市人口进行总和。鉴于下面的示例代码,它不起作用。你能帮我让它工作吗

输入是

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

2 回答 2

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>
于 2012-10-04T05:37:06.507 回答
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>
于 2012-10-04T12:08:06.337 回答