Как сформировать запрос для выбора на основе значения элемента - PullRequest
3 голосов
/ 10 мая 2011

У нас есть XML-документ со счетами / Invoice / [asst.elements], используя шаблон вызова xslt, нам нужно сложить InvoiceAmounts для сопоставления InvoiceNumbers.

Входной xml-файл:

    <Invoices>   
     <Invoice>  
      <InvoiceNumber>351510</InvoiceNumber> 
      <InvoiceAmount>137.50</InvoiceAmount> 
     </Invoice>   
     <Invoice>  
      <InvoiceNumber>351510</InvoiceNumber> 
      <InvoiceAmount>362.50</InvoiceAmount> 
     </Invoice>   
     <Invoice>  
      <InvoiceNumber>351511</InvoiceNumber> 
      <InvoiceAmount>239.50</InvoiceAmount> 
     </Invoice>  
    </Invoices>

Я нашел оператор выбора, который возвращает общую сумму InvoiceAmounts длявесь документ, но необходимо отфильтровать его до суммы, основанной на InvoiceNumber, поскольку в документе Invoices может быть несколько счетов с одним и тем же InvoiceNumber.

Возвращает общую сумму:

<xsl:value-of select="sum(/*[local-name()='Invoices']/*[local-name()='Invoice']/*[local-name()='InvoiceAmount'])" />

Согласно моим исследованиям, этот запрос ниже должен фильтровать результаты по одному InvoiceNumber, но это не так.Таким образом, мы добавили параметр в этот шаблон, p1, и отформатировали запрос ниже.Есть ли другой способ отформатировать этот выбор, чтобы получить общее количество только для тех InvoiceNumbers = $ p1?Перепробовав много вариантов этого, все еще не могу получить ожидаемые результаты.Есть ли способ добавить переменную $ p1 в выборку для фильтрации результатов?

<xsl:value-of select="sum(/*[local-name()='Invoices']/*[local-name()='Invoice'][local-name()='InvoiceAmount' = $p1]/*[local-name()='InvoiceAmount'])" />

Ожидаемые результаты:

<Invoices>
 <Invoice>
  <InvoiceNumber>351510</InvoiceNumber>
  <InvoiceAmount>500.00</InvoiceAmount>
 </Invoice>
 <Invoice>
  <InvoiceNumber>351510</InvoiceNumber>
  <InvoiceAmount>500.00</InvoiceAmount>
 </Invoice>
 <Invoice>
  <InvoiceNumber>351511</InvoiceNumber>
  <InvoiceAmount>239.50</InvoiceAmount>
 </Invoice>
</Invoices>

Спасибо за внимание.Том

Ответы [ 2 ]

1 голос
/ 10 мая 2011

Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="InvoiceAmount">
        <InvoiceAmount>
            <xsl:value-of 
               select="sum(../../Invoice[InvoiceNumber=
                   current()/parent::*/InvoiceNumber]/InvoiceAmount)"/>
       </InvoiceAmount>
    </xsl:template>
</xsl:stylesheet>

Производит:

<Invoices>   
     <Invoice>  
         <InvoiceNumber>351510</InvoiceNumber> 
         <InvoiceAmount>500</InvoiceAmount> 
     </Invoice>   
     <Invoice>  
         <InvoiceNumber>351510</InvoiceNumber> 
         <InvoiceAmount>500</InvoiceAmount> 
     </Invoice>   
     <Invoice>  
         <InvoiceNumber>351511</InvoiceNumber> 
         <InvoiceAmount>239.5</InvoiceAmount> 
     </Invoice>  
</Invoices>

Примечание: Форматирование денег оставлено в качестве упражнения.См. xsl:decimal-format.

0 голосов
/ 10 мая 2011

Это преобразование может быть более эффективным фактором , чем если бы ключи не использовались - особенно с большими документами XML:

<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:key name="kInvAmmtByNumber" match="InvoiceAmount"
  use="../InvoiceNumber"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="InvoiceAmount/text()">
  <xsl:value-of select=
  "sum(key('kInvAmmtByNumber', ../../InvoiceNumber))"/>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному XMLдокумент :

<Invoices>
    <Invoice>
        <InvoiceNumber>351510</InvoiceNumber>
        <InvoiceAmount>137.50</InvoiceAmount>
    </Invoice>
    <Invoice>
        <InvoiceNumber>351510</InvoiceNumber>
        <InvoiceAmount>362.50</InvoiceAmount>
    </Invoice>
    <Invoice>
        <InvoiceNumber>351511</InvoiceNumber>
        <InvoiceAmount>239.50</InvoiceAmount>
    </Invoice>
</Invoices>

желаемый, правильный результат :

<Invoices>
   <Invoice>
      <InvoiceNumber>351510</InvoiceNumber>
      <InvoiceAmount>500</InvoiceAmount>
   </Invoice>
   <Invoice>
      <InvoiceNumber>351510</InvoiceNumber>
      <InvoiceAmount>500</InvoiceAmount>
   </Invoice>
   <Invoice>
      <InvoiceNumber>351511</InvoiceNumber>
      <InvoiceAmount>239.5</InvoiceAmount>
   </Invoice>
</Invoices>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...