我有三个xml文件 stepProducts Product UserTypeID="Country" NameCyprus/Name Product UserTypeID="Resort" NameArgaka/Name Product UserTypeID="Property" NameVilla Tester/Name /Product /Product Product UserTypeID="Resort" NameCoral Bay/Name
<step> <Products> <Product UserTypeID="Country"> <Name>Cyprus</Name> <Product UserTypeID="Resort"> <Name>Argaka</Name> <Product UserTypeID="Property"> <Name>Villa Tester</Name> </Product> </Product> <Product UserTypeID="Resort"> <Name>Coral Bay</Name> <Product UserTypeID="Property"> <Name>1</Name> </Product> <Product UserTypeID="Property"> <Name>2</Name> </Product> </Product> </Product> <Product UserTypeID="Country"> <Name>Greece</Name> <Product UserTypeID="Region"> <Name>Corfu</Name> <Product UserTypeID="Resort"> <Name>Aghios Stefanos</Name> <Product UserTypeID="Property"> <Name>Villa Joanna</Name> </Product> <Product UserTypeID="Property"> <Name>Villa Eleonas</Name> </Product> </Product> <Product UserTypeID="Resort"> <Name>Kassiopi</Name> <Product UserTypeID="Property"> <Name>Villa 2</Name> </Product> </Product> </Product> </Product> </Products>
<step> <Products> <Product UserTypeID="Country"> <Name>Cyprus</Name> <Product UserTypeID="Resort"> <Name>Argaka</Name> <Product UserTypeID="Property"> <Name>Villa Jaime</Name> </Product> </Product> </Product> <Product UserTypeID="Country"> <Name>Greece</Name> <Product UserTypeID="Region"> <Name>Corfu</Name> <Product UserTypeID="Resort"> <Name>Acharavi</Name> <Product UserTypeID="Property"> <Name>Villa 1</Name> </Product> <Product UserTypeID="Property"> <Name>Villa 2</Name> </Product> </Product> <Product UserTypeID="Resort"> <Name>Gouvia</Name> <Product UserTypeID="Property"> <Name>Villa De Bono</Name> </Product> </Product> <Product UserTypeID="Resort"> <Name>Kassiopi</Name> <Product UserTypeID="Property"> <Name>Villa 1</Name> </Product> </Product> </Product> </Product> </Products>
<step> <Products> <Product UserTypeID="Country"> <Name>Cyprus</Name> <Product UserTypeID="Resort"> <Name>Aghia Marina</Name> <Product UserTypeID="Property"> <Name>Villa Aghia Marina</Name> </Product> </Product> <Product UserTypeID="Resort"> <Name>Coral Bay</Name> <Product UserTypeID="Property"> <Name>Ascos Coral Villas</Name> </Product> <Product UserTypeID="Property"> <Name>Coral Villa</Name> </Product> <Product UserTypeID="Property"> <Name>Lella Villas</Name> </Product> </Product> </Product> <Product UserTypeID="Country"> <Name>Greece</Name> <Product UserTypeID="Region"> <Name>Corfu</Name> <Product UserTypeID="Resort"> <Name>Acharavi</Name> <Product UserTypeID="Property"> <Name>Villa Angelos</Name> </Product> <Product UserTypeID="Property"> <Name>Villa Eleonas</Name> </Product> </Product> <Product UserTypeID="Resort"> <Name>Aghios Stefanos</Name> <Product UserTypeID="Property"> <Name>Villa Joanna</Name> </Product> <Product UserTypeID="Property"> <Name>Villa Eleonas</Name> </Product> </Product> <Product UserTypeID="Resort"> <Name>Kassiopi</Name> <Product UserTypeID="Property"> <Name>Villa Imerolia</Name> </Product> <Product UserTypeID="Property"> <Name>Test Property</Name> </Product> </Product> </Product> </Product> </Products>
每个文件都有相同的产品(通过./name),但有不同的子产品(通过./name),我需要将它们连接成一个树,每个产品/名称有一个产品,包含相同规则的所有子产品,以便我可以输出一个结构.
我找到了一个xslt方法,它将创建一个如下所示的节点集
<xsl:variable name="step-output"> <xsl:for-each select="/index/file"> <xsl:copy-of select="document(.)" /> </xsl:for-each> </xsl:variable> <xsl:variable name="step-products" select="exsl:node-set($step-output)//Products" />
但是,当我创建其他模板时,将按产品/名称创建三个产品,即塞浦路斯将出现三次.
有谁知道我怎么做我想要的?我的结果需要如下
<step> <Products> <Product UserTypeID="Country"> <Name>Cyprus</Name> <Product UserTypeID="Resort"> <Name>Aghia Marina</Name> <Product UserTypeID="Property"> <Name>Villa Aghia Marina</Name> </Product> </Product> <Product UserTypeID="Resort"> <Name>Argaka</Name> <Product UserTypeID="Property"> <Name>Villa Jaime</Name> </Product> <Product UserTypeID="Property"> <Name>Villa Tester</Name> </Product> </Product> <Product UserTypeID="Resort"> <Name>Coral Bay</Name> <Product UserTypeID="Property"> <Name>Ascos Coral Villas</Name> </Product> <Product UserTypeID="Property"> <Name>Coral Villa</Name> </Product> <Product UserTypeID="Property"> <Name>Lella Villas</Name> </Product> <Product UserTypeID="Property"> <Name>1</Name> </Product> <Product UserTypeID="Property"> <Name>2</Name> </Product> </Product> </Product> <Product UserTypeID="Country"> <Name>Greece</Name> <Product UserTypeID="Region"> <Name>Corfu</Name> <Product UserTypeID="Resort"> <Name>Acharavi</Name> <Product UserTypeID="Property"> <Name>Villa Angelos</Name> </Product> <Product UserTypeID="Property"> <Name>Villa Eleonas</Name> </Product> <Product UserTypeID="Property"> <Name>Villa 1</Name> </Product> <Product UserTypeID="Property"> <Name>Villa 2</Name> </Product> </Product> <Product UserTypeID="Resort"> <Name>Aghios Stefanos</Name> <Product UserTypeID="Property"> <Name>Villa Joanna</Name> </Product> <Product UserTypeID="Property"> <Name>Villa Eleonas</Name> </Product> </Product> <Product UserTypeID="Resort"> <Name>Gouvia</Name> <Product UserTypeID="Property"> <Name>Villa De Bono</Name> </Product> </Product> <Product UserTypeID="Resort"> <Name>Kassiopi</Name> <Product UserTypeID="Property"> <Name>Villa Imerolia</Name> </Product> <Product UserTypeID="Property"> <Name>Test Property</Name> </Product> <Product UserTypeID="Property"> <Name>Villa 1</Name> </Product> <Product UserTypeID="Property"> <Name>Villa 2</Name> </Product> </Product> </Product> </Product> </Products>这是一个应该完成工作的XSLT 2.0样式表:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:output indent="yes"/> <xsl:template match="/"> <step> <Products> <xsl:for-each-group select="document(index/file)/step/Products/Product" group-by="Name"> <Product UserTypeID="{@UserTypeID}"> <Name><xsl:value-of select="current-grouping-key()"/></Name> <xsl:for-each-group select="current-group()/Product" group-by="Name"> <xsl:sort select="current-grouping-key()"/> <Product UserTypeID="{@UserTypeID}"> <Name><xsl:value-of select="current-grouping-key()"/></Name> <xsl:for-each select="current-group()/Product"> <xsl:sort select="Name"/> <xsl:copy-of select="."/> </xsl:for-each> </Product> </xsl:for-each-group> </Product> </xsl:for-each-group> </Products> </step> </xsl:template> </xsl:stylesheet>
您需要针对具有该结构的索引XML文档运行它
<index> <file>test2010020803.xml</file> <file>test2010020804.xml</file> <file>test2010020805.xml</file> </index>
列出了您要处理的其他文件.
XSLT 2.0样式表可以用Saxon 9执行,它有.NET和Java版本,所以它可以在任何地方运行,至少Java 1.5或.NET 2.0可用或者可以安装.其他选项包括AltovaXML tools(仅限Windows)和Gestalt.
如果您绑定到XSLT 1.0,那么只要您有exsl:node-set或类似支持,就可以按如下方式执行:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl" version="1.0"> <xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <xsl:key name="k1" match="step/Products/Product" use="Name"/> <xsl:key name="k2" match="step/Products/Product/Product" use="concat(../Name, '|', Name)"/> <xsl:template match="/"> <xsl:variable name="rtf"> <xsl:copy-of select="document(index/file)/*"/> </xsl:variable> <step> <Products> <xsl:for-each select="exsl:node-set($rtf)/step/Products/Product[generate-id() = generate-id(key('k1', Name)[1])]"> <Product UserTypeID="{@UserTypeID}"> <xsl:copy-of select="Name"/> <xsl:for-each select="key('k1', Name)/Product[generate-id() = generate-id(key('k2', concat(../Name, '|', Name))[1])]"> <xsl:sort select="Name"/> <Product UserTypeID="{@UserTypeID}"> <xsl:copy-of select="Name"/> <xsl:for-each select="key('k2', concat(../Name, '|', Name))/Product"> <xsl:sort select="Name"/> <xsl:copy-of select="."/> </xsl:for-each> </Product> </xsl:for-each> </Product> </xsl:for-each> </Products> </step> </xsl:template> </xsl:stylesheet>
键看起来像这样:
<xsl:key name="k1" match="step/Products/Product" use="Name"/> <xsl:key name="k2" match="step/Products/Product/Product" use="concat(../Name, '|', Name)"/> <xsl:key name="k3" match="step/Products/Product/Product/Product" use="concat(../../Name, '|', ../Name, '|', Name)"/> <xsl:key name="k4" match="step/Products/Product/Product/Product/Product" use="concat(../../../Name, '|', ../../Name, '|', ../Name, '|', Name)"/> <xsl:key name="k5" match="step/Products/Product/Product/Product/Product/Product" use="concat(../../../../Name, '|', ../../../Name, '|', ../../Name, '|', ../Name, '|', Name)"/> <xsl:key name="k6" match="step/Products/Product/Product/Product/Product/Product/Product" use="concat(../../../../../Name, '|', ../../../../Name, '|', ../../../Name, '|', ../../Name, '|', ../Name, '|', Name)"/>
这些都直接在论坛编辑器中输入,因此可能有错误.