xml - xslt 1.0 使用复合键分组(在不同级别)

标签 xml xslt muenchian-grouping

我有一个转换,我试图记录一组扁平化的交易详细信息,并在文件末尾提供按投标类型和登记号分组的总数的总和。
记录一组单独的交易详细信息是很容易的部分,而且我工作得很好,但我在总结部分上遇到了困难。

问题是我不知道有什么或有多少个不同的寄存器号,或者有什么或有多少个投标类型(因此在 xslt 中使用静态过滤字符串明确列出摘要是不行的) ,因此某种分组似乎是合适的。

再加一把 Spanner – 我在使用 XSLT 1.0 时陷入困境......

我尝试搞乱 muenchian 分组,但是在复合 key 要求(寄存器与付款方式处于不同级别)和我对 muenchian 方法和 key 如何工作的有限理解之间,我无法首先做到这一点似乎让它发挥作用,但我认为这仍然可能是需要的技巧......

关于我如何神奇地让它发挥作用有什么建议吗?

这是一个示例源文档:

<s0:SalesCollection xmlns:s0="http://mySourceSchema">
  <s0:Sale transactionnumber="1" register="1">
    <s0:Tender amount="1.11" paymentmethod="visa" />
    <s0:Tender amount="2.22" paymentmethod="mastercard" />
  </s0:Sale>
  <s0:Sale transactionnumber="2" register="1">
    <s0:Tender amount="5.55" paymentmethod="discover" />
    <s0:Tender amount="4.44" paymentmethod="visa" />
  </s0:Sale>
  <s0:Sale transactionnumber="1" register="2">
    <s0:Tender amount="9.99" paymentmethod="amex" />
    <s0:Tender amount="8.88" paymentmethod="visa" />
  </s0:Sale>
</s0:SalesCollection>

这就是我想要的(同样,我已经有记录[@type='detail']记录在工作):

<ns0:root xmlns:ns0="http://myDestinationSchema">
  <ns0:record type="detail" transactionnumber="1" register="1" amount="1.11" paymentmethod="visa" />
  <ns0:record type="detail" transactionnumber="1" register="1" amount="2.22" paymentmethod="mastercard" />
  <ns0:record type="detail" transactionnumber="2" register="1" amount="5.55" paymentmethod="discover" />
  <ns0:record type="detail" transactionnumber="2" register="1" amount="4.44" paymentmethod="visa" />
  <ns0:record type="detail" transactionnumber="1" register="2" amount="9.99" paymentmethod="amex" />
  <ns0:record type="detail" transactionnumber="1" register="2" amount="8.88" paymentmethod="visa" />
  <ns0:record type="summary" register="1" amount="5.55" paymentmethod="visa" />
  <ns0:record type="summary" register="1" amount="2.22" paymentmethod="mastercard" />
  <ns0:record type="summary" register="1" amount="5.55" paymentmethod="discover" />
  <ns0:record type="summary" register="2" amount="9.99" paymentmethod="amex" />
  <ns0:record type="summary" register="2" amount="8.88" paymentmethod="visa" />
</ns0:root>

那么如何使用 xslt 1.0 创建按注册和付款方式分组的摘要记录?

最佳答案

这种转变:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:s0="http://mySourceSchema"
 xmlns:ns0="http://myDestinationSchema" exclude-result-prefixes="s0">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kTendByTypeAndReg" match="s0:Tender"
  use="concat(../@register, '#', @paymentmethod)"/>

 <xsl:template match="/*">
  <ns0:root xmlns:ns0="http://myDestinationSchema">
   <xsl:apply-templates select="*/*"/>
   <xsl:apply-templates mode="group" select=
   "*/*[generate-id()
       =generate-id(key('kTendByTypeAndReg',
                        concat(../@register, '#', @paymentmethod))[1]
                        )
       ]"/>
  </ns0:root>
 </xsl:template>

 <xsl:template match="s0:Tender">
   <ns0:record type="detail" transactionnumber="{../@transactionnumber}"
       register="{../@register}" amount="{@amount}" paymentmethod="{@paymentmethod}" />
 </xsl:template>

 <xsl:template match="*" mode="group">
    <ns0:record type="summary" register="{../@register}" paymentmethod="{@paymentmethod}"
  amount="{sum(key('kTendByTypeAndReg',concat(../@register,'#',@paymentmethod))
                   /@amount)}"/>
 </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时:

<s0:SalesCollection xmlns:s0="http://mySourceSchema">
  <s0:Sale transactionnumber="1" register="1">
    <s0:Tender amount="1.11" paymentmethod="visa" />
    <s0:Tender amount="2.22" paymentmethod="mastercard" />
  </s0:Sale>
  <s0:Sale transactionnumber="2" register="1">
    <s0:Tender amount="5.55" paymentmethod="discover" />
    <s0:Tender amount="4.44" paymentmethod="visa" />
  </s0:Sale>
  <s0:Sale transactionnumber="1" register="2">
    <s0:Tender amount="9.99" paymentmethod="amex" />
    <s0:Tender amount="8.88" paymentmethod="visa" />
  </s0:Sale>
</s0:SalesCollection>

产生想要的结果:

<ns0:root xmlns:ns0="http://myDestinationSchema">
    <ns0:record type="detail" transactionnumber="1" register="1" amount="1.11" paymentmethod="visa"/>
    <ns0:record type="detail" transactionnumber="1" register="1" amount="2.22" paymentmethod="mastercard"/>
    <ns0:record type="detail" transactionnumber="2" register="1" amount="5.55" paymentmethod="discover"/>
    <ns0:record type="detail" transactionnumber="2" register="1" amount="4.44" paymentmethod="visa"/>
    <ns0:record type="detail" transactionnumber="1" register="2" amount="9.99" paymentmethod="amex"/>
    <ns0:record type="detail" transactionnumber="1" register="2" amount="8.88" paymentmethod="visa"/>
    <ns0:record type="summary" register="1" paymentmethod="visa" amount="5.55"/>
    <ns0:record type="summary" register="1" paymentmethod="mastercard" amount="2.22"/>
    <ns0:record type="summary" register="1" paymentmethod="discover" amount="5.55"/>
    <ns0:record type="summary" register="2" paymentmethod="amex" amount="9.99"/>
    <ns0:record type="summary" register="2" paymentmethod="visa" amount="8.88"/>
</ns0:root>

说明:

正确使用:

  1. Muenchian Grouping method

  2. AVT s(属性值模板)。

关于xml - xslt 1.0 使用复合键分组(在不同级别),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16181191/

相关文章:

iphone - Safari 中不支持 XSLTProcessor() 吗?

xslt - 如何编写 XSLT 以在 HTML 表中每次出现同级节点时重复同级节点值

xml - 使用 XSLT muenchian 分组来计算运动队排名(胜/负)?

xml - 仅为 XSL 1.0 中的特定条件列出组内属性的唯一值

java - 使用 Muenchian 分组方法的 XSLT 问题

xml - 用于转换结构的 XSLT + 用于转换值的 Ruby?

java - 使用类型化类和 rdf 创建 RDF 模型 :id

xml - 用带有 xslt 的字符串替换字符串

php - 通过 PHP 从字符串中删除特定的 XML 标签

mysql - 重新格式化大型 XML 文件的简单方法?