嗨我有一个像xml结构的树......我想用XSLT来转换它来计算productPrices ...如果它是一个线性结构我可以使用一个简单的求和函数,名字上有一个过滤器......但是作为一个树状结构,它需要某种递归转换...有人可以建议我做一些技术或方法来进行这种转换...我试图从我的结尾写出它...如果你有帮助可以提出一些方法......
<?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>
答案 0 :(得分:3)
以下是完整的解决方案:
<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
元素总和是直截了当的。
不需要递归。
答案 1 :(得分:0)
好吧,给你指路..
您可以先为Product
元素编写模板。
使用xsl:for-each
并递归应用相同的模板。 (查看递归模板)
正如您所建议的那样,您需要巧妙地使用xsl:variables
sum()
功能。
答案 2 :(得分:0)
再次感谢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>
Stackoverflow和这里的专家很棒......再次感谢!