Как использовать для каждой группы в xslt - PullRequest
0 голосов
/ 01 февраля 2020

Я хочу удалить дублирующее значение (штрих-код) в моем xml, используя «для каждой группы»

Это мой xml

<?xml version='1.0' encoding='UTF-8'?>
<multimap:Messages xmlns:multimap="http://sap.com/xi/XI/SplitAndMerge">
    <multimap:Message1>
        <bookRoot>
            <bookRecord>
                <barcode>1111</barcode>
                <modifiedDate>2019-04-04T05:11:59.000Z</modifiedDate>
            </bookRecord>
            <bookRecord>
                <barcode>2222</barcode>
                <modifiedDate>2019-11-07T15:00:23.000Z</modifiedDate>
            </bookRecord>
            <bookRecord>
                <barcode>1111</barcode>
                <modifiedDate>2020-01-11T05:51:23.000Z</modifiedDate>
            </bookRecord>
        </bookRoot>
        <bookRoot>
            <bookRecord>
                <barcode>1111</barcode>
                <modifiedDate>2019-09-15T15:16:09.000Z</modifiedDate>
            </bookRecord>
            <bookRecord>
                <barcode>9999</barcode>
                <modifiedDate>2019-12-31T10:00:23.000Z</modifiedDate>
            </bookRecord>
        </bookRoot>
    </multimap:Message1>
</multimap:Messages>

Это мой ожидаемый xml

<?xml version="1.0" encoding="UTF-8"?>
<storeRoot>
   <storeRecord>1111</storeRecord>
   <storeRecord>2222</storeRecord>
   <storeRecord>9999</storeRecord>
</storeRoot>

Я пытался использовать для каждой группы по группе штрих-код

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="bookRoot">
    <storeRoot>
        <xsl:for-each-group select="bookRecord" group-by="barcode">
            <xsl:sort select='barcode' order="ascending"  data-type="number"/>
            <storeRecord>
                <xsl:apply-templates select="barcode"/>
            </storeRecord>
        </xsl:for-each-group>
    </storeRoot>
</xsl:template>
</xsl:stylesheet>

Это мой фактический результат.

<?xml version="1.0" encoding="UTF-8"?>
<storeRoot>
   <storeRecord>1111</storeRecord>
   <storeRecord>2222</storeRecord>
</storeRoot>
<storeRoot>
   <storeRecord>1111</storeRecord>
   <storeRecord>9999</storeRecord>
</storeRoot>

Я все еще получил дубликат записи "1111". Как я могу удалить дубликаты записей штрих-кода?

Ответы [ 2 ]

2 голосов
/ 01 февраля 2020

Ваш шаблон соответствует bookRoot - и во входе XML есть два экземпляра книги Root. Поэтому вы получаете два экземпляра storeRoot, каждый из которых группирует свое собственное подмножество bookRoot узлов.

Попробуйте вместо этого:

<xsl:template match="/">
    <storeRoot>
        <xsl:for-each-group select="//bookRecord" group-by="barcode">
            <xsl:sort select='barcode' order="ascending"  data-type="number"/>
            <storeRecord>
                <xsl:apply-templates select="barcode"/>
            </storeRecord>
        </xsl:for-each-group>
    </storeRoot>
</xsl:template>
0 голосов
/ 01 февраля 2020

В качестве альтернативы, если вы просто хотите найти уникальные значения, в XSLT 2/3 вы можете сделать это с помощью distinct-values(//barcode/xs:integer(.)):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    expand-text="yes"
    version="3.0">

  <xsl:output indent="yes"/>

  <xsl:template match="/">
      <storeRoot>
          <xsl:for-each select="distinct-values(//barcode/xs:integer(.))">
              <storeCode>{.}</storeCode>
          </xsl:for-each>
      </storeRoot>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/gWEaSv9

В XSLT 3 такой список значений даже можно отсортировать с помощью XPath и его функции sort: distinct-values(//barcode/xs:integer(.)) => sort(()):

  <xsl:template match="/">
      <storeRoot>
          <xsl:for-each select="distinct-values(//barcode/xs:integer(.)) => sort(())">
              <storeCode>{.}</storeCode>
          </xsl:for-each>
      </storeRoot>
  </xsl:template>

https://xsltfiddle.liberty-development.net/gWEaSv9/1

...