Вы не точно дать понять, что вы пробовали писать XSLT-код самостоятельно. Я покажу вам, как обрабатывать элементы Expense
. Написать
- шаблон, который выполняет тождественное преобразование, чтобы скопировать выводится исходной
- шаблоном, который совпадает с первым
Expense
элемента, и пусть его содержанием будет суммой всех Expense
детей своего родительского элемента
- в шаблон, который соответствует последующим
Expense
элементов и что не делает ничего
XML Input
Предполагая следующее, хорошо сформированную вход (добавленный </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.
Есть ли разница между 'Расход [not (предшествующий-братьев: Расход)]' и 'Расход [1]'? –
@ michael.hor257k Нет, согласен. Я редактировал таблицу стилей. –