Munechian группировки и сортировки XSLt 1.0 - PullRequest
0 голосов
/ 22 января 2020

У меня есть требование, где мне нужно сделать сортировку и группировку. Я работал с моим XSLT с сортировкой, но он не дает желаемого результата,

Ввод XML:

<ns0:Root xmlns:ns0="http://TestXSLT1._0.Output">
  <SeqNo>1</SeqNo>
  <FileName>Test</FileName>
  <DestinationLocation>Miami</DestinationLocation>
  <DestinationName>State</DestinationName>
  <Detail>
    <ItemName>Item1</ItemName>
    <Rate>100</Rate>
  </Detail>
  <Detail>
    <ItemName>Item2</ItemName>
    <Rate>200</Rate>
  </Detail>
  <Detail>
    <ItemName>Item3</ItemName>
    <Rate>300</Rate>
  </Detail>
  <Detail>
    <ItemName>Item1</ItemName>
    <Quantity>1</Quantity>
  </Detail>
  <Detail>
    <ItemName>Item2</ItemName>
    <Quantity>2</Quantity>
  </Detail>
</ns0:Root>

Желаемый выход: Что я ожидаю

 <ns0:Root xmlns:ns0="http://TestXSLT1._0.Output">
        <SeqNo>1</SeqNo>
        <FileName>Test</FileName>
        <DestinationLocation>Miami</DestinationLocation>
        <DestinationName>State</DestinationName>
        <Detail>
            <ItemName>Item1</ItemName>
            <Quantity>1</Quantity>
            <Rate>100</Rate>
        </Detail>
        <Detail>
            <ItemName>Item2</ItemName>
            <Quantity>2</Quantity>
            <Rate>200</Rate>
        </Detail>
        <Detail>
            <ItemName>Item3</ItemName>
            <Rate>3</Rate>
        </Detail>
    </ns0:Root>

XSLT Я работал:

<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var" version="1.0" xmlns:ns0="http://TestXSLT1._0.Output">
  <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
  <xsl:key name="group" match="Detail" use="ItemName"/>
  <xsl:key name="group1" match="Detail" use="Rate"/>
  <xsl:template match="/">
    <xsl:apply-templates select="/ns0:Root" />
  </xsl:template>
  <xsl:template match="/ns0:Root">
    <ns0:Root>
      <xsl:if test="SeqNo">
        <SeqNo>
          <xsl:value-of select="SeqNo/text()" />
        </SeqNo>
      </xsl:if>
      <xsl:if test="FileName">
        <FileName>
          <xsl:value-of select="FileName/text()" />
        </FileName>
      </xsl:if>
      <xsl:if test="DestinationLocation">
        <DestinationLocation>
          <xsl:value-of select="DestinationLocation/text()" />
        </DestinationLocation>
      </xsl:if>
      <xsl:if test="DestinationName">
        <DestinationName>
          <xsl:value-of select="DestinationName/text()" />
        </DestinationName>
      </xsl:if>
      <xsl:for-each select="Detail[generate-id(.)=generate-id(key('group',ItemName))]">
        <Detail>
          <xsl:if test="ItemName">
            <ItemName>
              <xsl:value-of select="ItemName/text()" />
            </ItemName>
          </xsl:if>
          <xsl:if test="Quantity">
            <Quantity>
              <xsl:value-of select="Quantity/text()" />
            </Quantity>
          </xsl:if>
          <xsl:if test="Rate">
            <Rate>
              <xsl:value-of select="sum(key('group1', Rate)/Rate)" />
            </Rate>
          </xsl:if>
        </Detail>
      </xsl:for-each>
    </ns0:Root>
  </xsl:template>
</xsl:stylesheet>

XSLT, который я сделал, не дает мне желаемого результата. Это должно быть сделано в XSLT 1.0. Оцените помощь

1 Ответ

1 голос
/ 22 января 2020

AFAICT, вы просто хотите сгруппировать узлы Detail по ItemName. Это можно сделать просто используя:

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" omit-xml-declaration="yes"/>

<xsl:key name="detail-by-item" match="Detail" use="ItemName"/>

<xsl:template match="/*">
    <xsl:copy>
        <xsl:copy-of select="*[not(self::Detail)]"/>
        <xsl:for-each select="Detail[generate-id()=generate-id(key('detail-by-item', ItemName))]">
            <xsl:copy>
                <xsl:copy-of select="ItemName"/>
                <xsl:copy-of select="key('detail-by-item', ItemName)/*[not(self::ItemName)]"/>
            </xsl:copy>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
...