我有三个xml文件
<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>
答案 0 :(得分:4)
这是一个应该完成工作的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)"/>
这一切都直接在论坛编辑器中输入,因此可能有错误。
答案 1 :(得分:0)
编辑文本以创建文件将起作用,但可能难以维护。
最简单的方法是将所有3个文件的XML解析为对象形式。以编程方式在单个父节点下添加对象,然后重新生成新的XML文件。
您的环境是否可以将此作为可接受的解决方案?