2014-11-27 2 views
0

Просьба сообщить, как я могу добиться следующего преобразования.Вычисление суммы из идентичных тегов

Ввод 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> 

Благодаря

ответ

1

Вы не точно дать понять, что вы пробовали писать 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()]) &gt; 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.

+0

Есть ли разница между 'Расход [not (предшествующий-братьев: Расход)]' и 'Расход [1]'? –

+0

@ michael.hor257k Нет, согласен. Я редактировал таблицу стилей. –

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> 
Смежные вопросы