我想对有城市人口的每个国家的人口进行总结。考虑到下面的示例代码,它无法正常工作。你能不能帮助我让它工作
输入
<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 :(得分: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>
答案 1 :(得分: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>