需要一个XSLT转换
嗨我有一个像xml结构树...我想使用XSLT来转换它来计算productPrices ...如果它是一个线性结构我可以使用一个简单的sum函数与一个名称上的过滤器...但是,因为它像结构树一样需要某种递归转换......有人可以建议我使用一些技术或方法来完成这种转换......我试图从我的结尾写下它......它会如果你可以建议一些方法,请帮助...需要一个XSLT转换
<?xml version="1.0" encoding="UTF-8"?>
<Products>
<Product>
<Name>X2</Name>
<Price>1</Price>
<Product>
<Name>X1</Name>
<Price>1</Price>
<Product>
<Name>X1</Name>
<Price>1</Price>
</Product>
<Product>
<Name>X2</Name>
<Price>1</Price>
</Product>
</Product>
<Product>
<Name>X2</Name>
<Price>1</Price>
<Product>
<Name>X1</Name>
<Price>1</Price>
</Product>
<Product>
<Name>X1</Name>
<Price>1</Price>
<Product>
<Name>X2</Name>
<Price>1</Price>
</Product>
</Product>
</Product>
</Product>
<Description>
<text>dsd</text>
</Description>
<Description>
<text>dsd</text>
</Description>
</Products>
我需要它的最终结构。
<?xml version="1.0" encoding="UTF-8"?>
<Products>
<Product>
<Name>X2</Name>
<Price>1</Price>
<!--Total Price of X2 Products-->
<TotalPrice>4</TotalPrice>
<Product>
<Name>X1</Name>
<Price>1</Price>
<!--Total Price of X1 Products-->
<TotalPrice>4</TotalPrice>
<Product>
<Name>X1</Name>
<Price>1</Price>
<!--Total Price of X1 Products-->
<TotalPrice>4</TotalPrice>
</Product>
<Product>
<Name>X2</Name>
<Price>1</Price>
<!--Total Price of X2 Products-->
<TotalPrice>4</TotalPrice>
</Product>
</Product>
<Product>
<Name>X2</Name>
<Price>1</Price>
<!--Total Price of X2 Products-->
<TotalPrice>4</TotalPrice>
<Product>
<Name>X1</Name>
<Price>1</Price>
<!--Total Price of X1 Products-->
<TotalPrice>4</TotalPrice>
</Product>
<Product>
<Name>X1</Name>
<Price>1</Price>
<!--Total Price of X1 Products-->
<TotalPrice>4</TotalPrice>
<Product>
<Name>X2</Name>
<Price>1</Price>
<!--Total Price of X2 Products-->
<TotalPrice>4</TotalPrice>
</Product>
</Product>
</Product>
</Product>
<Description>
<text>dsd</text>
</Description>
<Description>
<text>dsd</text>
</Description>
</Products>
好了,给你方向..
你可以写一个模板,一个Product
元素开始。使用xsl:for-each
并递归应用相同的模板。 (查看递归模板)
正如您所建议的,您将需要巧妙地使用xsl:variables
以及sum()
函数。
下面是一个完整的解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vProd1TotalPrice"
select="sum(//Product[Name='X1']/Price)"/>
<xsl:variable name="vProd2TotalPrice"
select="sum(//Product[Name='X2']/Price)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Product">
<xsl:copy>
<xsl:apply-templates select="*[not(self::Product)]"/>
<TotalPrice>
<xsl:value-of select=
"$vProd1TotalPrice *(Name='X1')
+
$vProd2TotalPrice *(Name='X2')
"/>
</TotalPrice>
<xsl:apply-templates select="Product"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当这个变换所提供的XML文档应用:
<Products>
<Product>
<Name>X2</Name>
<Price>1</Price>
<Product>
<Name>X1</Name>
<Price>1</Price>
<Product>
<Name>X1</Name>
<Price>1</Price>
</Product>
<Product>
<Name>X2</Name>
<Price>1</Price>
</Product>
</Product>
<Product>
<Name>X2</Name>
<Price>1</Price>
<Product>
<Name>X1</Name>
<Price>1</Price>
</Product>
<Product>
<Name>X1</Name>
<Price>1</Price>
<Product>
<Name>X2</Name>
<Price>1</Price>
</Product>
</Product>
</Product>
</Product>
<Description>
<text>dsd</text>
</Description>
<Description>
<text>dsd</text>
</Description>
</Products>
有用,正确的结果产生:
<Products>
<Product>
<Name>X2</Name>
<Price>1</Price>
<TotalPrice>4</TotalPrice>
<Product>
<Name>X1</Name>
<Price>1</Price>
<TotalPrice>4</TotalPrice>
<Product>
<Name>X1</Name>
<Price>1</Price>
<TotalPrice>4</TotalPrice>
</Product>
<Product>
<Name>X2</Name>
<Price>1</Price>
<TotalPrice>4</TotalPrice>
</Product>
</Product>
<Product>
<Name>X2</Name>
<Price>1</Price>
<TotalPrice>4</TotalPrice>
<Product>
<Name>X1</Name>
<Price>1</Price>
<TotalPrice>4</TotalPrice>
</Product>
<Product>
<Name>X1</Name>
<Price>1</Price>
<TotalPrice>4</TotalPrice>
<Product>
<Name>X2</Name>
<Price>1</Price>
<TotalPrice>4</TotalPrice>
</Product>
</Product>
</Product>
</Product>
<Description>
<text>dsd</text>
</Description>
<Description>
<text>dsd</text>
</Description>
</Products>
说明:
这是直截了当的,以指定在一个单一的XPath表达式Price
元件的所需金额作为代码定义两个全局变量时完成。
没有递归是必要的。
再次感谢Dimitre ......我修改了XSLT,使其一点点通用...现在它看起来像这样...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-16" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Product">
<xsl:variable name="ProductLine" select="."/>
<xsl:copy>
<xsl:apply-templates select="*[not(self::Product)]"/>
<TotalPrice>
<xsl:value-of select="sum(//Product[Name=$ProductLine/Name]/Price)"/>
</TotalPrice>
<xsl:apply-templates select="Product"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
所以,如果我给一个修改后的XML如下。
<?xml version="1.0" encoding="UTF-8"?>
<Products>
<Product>
<Name>X2</Name>
<Price>1</Price>
<Product>
<Name>X1</Name>
<Price>1</Price>
<Product>
<Name>X1</Name>
<Price>1</Price>
</Product>
<Product>
<Name>X3</Name>
<Price>1</Price>
</Product>
</Product>
<Product>
<Name>X2</Name>
<Price>1</Price>
<Product>
<Name>X3</Name>
<Price>1</Price>
</Product>
<Product>
<Name>X1</Name>
<Price>1</Price>
<Product>
<Name>X2</Name>
<Price>1</Price>
</Product>
</Product>
</Product>
</Product>
<Description>
<text>dsd</text>
</Description>
<Description>
<text>dsd</text>
</Description>
</Products>
它仍然给我的输出如下。
<?xml version="1.0" encoding="UTF-16"?>
<Products>
<Product>
<Name>X2</Name>
<Price>1</Price>
<TotalPrice>3</TotalPrice>
<Product>
<Name>X1</Name>
<Price>1</Price>
<TotalPrice>3</TotalPrice>
<Product>
<Name>X1</Name>
<Price>1</Price>
<TotalPrice>3</TotalPrice>
</Product>
<Product>
<Name>X3</Name>
<Price>1</Price>
<TotalPrice>2</TotalPrice>
</Product>
</Product>
<Product>
<Name>X2</Name>
<Price>1</Price>
<TotalPrice>3</TotalPrice>
<Product>
<Name>X3</Name>
<Price>1</Price>
<TotalPrice>2</TotalPrice>
</Product>
<Product>
<Name>X1</Name>
<Price>1</Price>
<TotalPrice>3</TotalPrice>
<Product>
<Name>X2</Name>
<Price>1</Price>
<TotalPrice>3</TotalPrice>
</Product>
</Product>
</Product>
</Product>
<Description>
<text>dsd</text>
</Description>
<Description>
<text>dsd</text>
</Description>
</Products>
#1和这里的专家们真棒......再次感谢!
由于'$ ProductLine/Name'是无环境的,因此您可以将'$ ProductName'声明为'Name'而不是'$ ProductLine'作为'.' – 2011-03-16 17:54:58
@bejoy:我可以提出一点改革吗?您可以将'Name'和'Price'作为'Product'元素的属性。使嵌套可读并且易于迭代。 – 2011-03-16 06:56:33
@conqenator:感谢您的评论,但不可修改的结构... – Joy 2011-03-16 07:17:15
@bejoy:那么你想知道什么?在你的“需求”上面没有问题。根据常见问题,我被迫变得很好,但让我说这不是一个你扔东西,让别人完成你的工作的地方。如果您对文档进行转换时遇到具体问题,请随时发布您的问题,并确保获得一个很好的答案。 – Chris 2011-03-16 07:34:29