请告知我如何实现以下转型。
我输入的xml格式为。
<Employees>
<Employee>
<Name>Don</Name>
<Salary>5000</Salary>
<Expense>1000</Expense>
<Expense>500</Expense>
<Expense>300</Expense>
</Employee>
<Employee>
<Name>John</Name>
<Salary>5000</Salary>
<Expense>100</Expense>
<Expense>400</Expense>
<Tax>500</Tax>
<Tax>200</Tax>
</Employee>
输出应为
<Employees>
<Employee>
<Name>Don</Name>
<Salary>5000</Salary>
<Expense>1800</Expense>
</Employee>
<Employee>
<Name>John</Name>
<Salary>6000</Salary>
<Expense>500</Expense>
<Tax>700</Tax>
</Employee>
由于
答案 0 :(得分:1)
您并没有明确表示您自己尝试编写XSLT代码。我将向您展示如何处理Expense
元素。写
Expense
元素匹配的模板,并让其内容为其父元素的所有Expense
子元素的总和Expense
元素匹配但不执行任何操作的模板XML输入
假设以下结构良好的输入(在末尾添加</Employees>
):
<Employees>
<Employee>
<Name>Don</Name>
<Salary>5000</Salary>
<Expense>1000</Expense>
<Expense>500</Expense>
<Expense>300</Expense>
</Employee>
<Employee>
<Name>John</Name>
<Salary>5000</Salary>
<Expense>100</Expense>
<Expense>400</Expense>
<Tax>500</Tax>
<Tax>200</Tax>
</Employee>
</Employees>
<强>样式表强>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" encoding="utf-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Expense[1]">
<xsl:copy>
<xsl:value-of select="sum(../Expense)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Expense"/>
</xsl:stylesheet>
XML输出
<?xml version="1.0" encoding="utf-8"?>
<Employees>
<Employee>
<Name>Don</Name>
<Salary>5000</Salary>
<Expense>1800</Expense>
</Employee>
<Employee>
<Name>John</Name>
<Salary>5000</Salary>
<Expense>500</Expense>
<Tax>500</Tax>
<Tax>200</Tax>
</Employee>
</Employees>
要将此类处理应用于Employee
的任何子级,请使用类似
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" encoding="utf-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*/*/*[count(../*[name() = current()/name()]) > 1 and not(preceding-sibling::*[name() = current()/name()] ) ] ">
<xsl:element name="{name()}">
<xsl:value-of select="sum(../*[name() = current()/name()])"/>
</xsl:element>
</xsl:template>
<xsl:template match="*/*/*[preceding-sibling::*[name() = current()/name()]]"/>
</xsl:stylesheet>
结果是
<?xml version="1.0" encoding="utf-8"?>
<Employees>
<Employee>
<Name>Don</Name>
<Salary>5000</Salary>
<Expense>1800</Expense>
</Employee>
<Employee>
<Name>John</Name>
<Salary>5000</Salary>
<Expense>500</Expense>
<Tax>700</Tax>
</Employee>
</Employees>
并且还显示您的预期输出是错误的 - 约翰的薪水当然应该保持在5000,而不是变为6000。
答案 1 :(得分:1)
我相信我会做的很简单:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/Employees">
<Employees>
<xsl:for-each select="Employee">
<Employee>
<xsl:copy-of select="Name"/>
<Salary>
<xsl:value-of select="sum(Salary)"/>
</Salary>
<Expense>
<xsl:value-of select="sum(Expense)"/>
</Expense>
<Tax>
<xsl:value-of select="sum(Tax)"/>
</Tax>
</Employee>
</xsl:for-each>
</Employees>
</xsl:template>
</xsl:stylesheet>
结果(与预期略有不同):
<?xml version="1.0" encoding="utf-8"?>
<Employees>
<Employee>
<Name>Don</Name>
<Salary>5000</Salary>
<Expense>1800</Expense>
<Tax>0</Tax>
</Employee>
<Employee>
<Name>John</Name>
<Salary>5000</Salary>
<Expense>500</Expense>
<Tax>700</Tax>
</Employee>
</Employees>
如果您愿意,可以有条件地输出任何或所有摘要,例如
<xsl:if test="Tax">
<Tax>
<xsl:value-of select="sum(Tax)"/>
</Tax>
</xsl:if>