请告诉我如何实现以下转换。
我拥有的输入 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>
谢谢
我相信
我会简单地做:
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>
您没有明确表示您尝试过自己编写 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。