Группировать XML файл на основе заданного числа с использованием XSLT - PullRequest
0 голосов
/ 27 марта 2020

Я хочу сгруппировать файл XML на основе значения тега XML. Ниже мой ввод XML.

<Root>
    <GroupNumber>3</GroupNumber>
    <EDICustomer>
        <Company>IWS</Company>
        <Customer>150</Customer>
        <CreationDate>2020-03-15T10:29:08.813</CreationDate>
        <CreationTime>2020-03-15T10:29:08.813</CreationTime>
        <EDICustomerLine>
            <Barcode>447896130245</Barcode>
            <ItemDescription>Medium</ItemDescription>
            <Warehouse>B01</Warehouse>
            <Status>12</Status>
        </EDICustomerLine>
        <EDICustomerLine>
            <Barcode>447896130245</Barcode>
            <ItemDescription>Medium</ItemDescription>
            <Warehouse>B01</Warehouse>
            <Status>12</Status>
        </EDICustomerLine>
        <EDICustomerLine>
            <Barcode>447896130245</Barcode>
            <ItemDescription>Medium</ItemDescription>
            <Warehouse>B01</Warehouse>
            <Status>12</Status>
        </EDICustomerLine>
        <EDICustomerLine>
            <Barcode>447896130245</Barcode>
            <ItemDescription>Medium</ItemDescription>
            <Warehouse>B01</Warehouse>
            <Status>12</Status>
        </EDICustomerLine>
    </EDICustomer>
</Root>

Я не знаю, сколько будет тэгов EDICustomerLine. Если значение GroupNumber больше, чем количество тегов EDICustomerLine, оставьте дочерние теги EDICustomer без изменений, но если значение GroupNumber меньше тегов EDICustomerLine, мы должны разделить теги EDICustomerLine на основе значения тега GroupNumber. Таким образом, в этом сценарии ожидаемый XML будет выглядеть следующим образом.

<Root>
    <EDICustomer>
        <Company>IWS</Company>
        <Customer>150</Customer>
        <CreationDate>2020-03-15T10:29:08.813</CreationDate>
        <CreationTime>2020-03-15T10:29:08.813</CreationTime>
        <EDICustomerLine>
            <Barcode>447896130245</Barcode>
            <ItemDescription>Medium</ItemDescription>
            <Warehouse>B01</Warehouse>
            <Status>12</Status>
        </EDICustomerLine>
        <EDICustomerLine>
            <Barcode>447896130245</Barcode>
            <ItemDescription>Medium</ItemDescription>
            <Warehouse>B01</Warehouse>
            <Status>12</Status>
        </EDICustomerLine>
        <EDICustomerLine>
            <Barcode>447896130245</Barcode>
            <ItemDescription>Medium</ItemDescription>
            <Warehouse>B01</Warehouse>
            <Status>12</Status>
        </EDICustomerLine>
    </EDICustomer>
    <EDICustomer>
        <Company>IWS</Company>
        <Customer>150</Customer>
        <CreationDate>2020-03-15T10:29:08.813</CreationDate>
        <CreationTime>2020-03-15T10:29:08.813</CreationTime>
        <EDICustomerLine>
            <Barcode>447896130245</Barcode>
            <ItemDescription>Medium</ItemDescription>
            <Warehouse>B01</Warehouse>
            <Status>12</Status>
        </EDICustomerLine>
    </EDICustomer>
</Root>

Первый родительский тег EDICustomer содержит Company, Customer, CreationDate, CreationTime и 3 на основе значения номера группы. Как и второй EDICustomer должен содержать не более 3 тегов. Мы не знаем, сколько будет тегов EDICustomerLine и значение номера группы. Также

<Company>IWS</Company>
        <Customer>150</Customer>
        <CreationDate>2020-03-15T10:29:08.813</CreationDate>
        <CreationTime>2020-03-15T10:29:08.813</CreationTime>

Эта часть выше должна повторяться во всех группах EDICustomer (эта часть будет возможна, если мы найдем путь к l oop EDICustomerLine на основе номера группы).

First Из всего, что я хочу знать, возможен ли этот сценарий в XSLT.
Если возможно, вы, ребята, можете мне помочь?

1 Ответ

0 голосов
/ 27 марта 2020

Вы можете достичь желаемого результата с помощью следующей таблицы стилей XSLT-2.0. Он группирует элементы <EDICustomerLine> в группы по GroupNumber, а затем выполняет итерацию по current-group(). Постоянная часть создается первым xsl:copy-of.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="text()" />

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

   <xsl:template match="Root">
     <xsl:variable name="max" select="GroupNumber" />
     <xsl:copy>
        <!-- Handle the "zero-items" situation" -->
        <xsl:if test="count(EDICustomer/EDICustomerLine) = 0">
            <EDICustomer>
                <xsl:copy-of select="EDICustomer[1]/Company | EDICustomer[1]/Customer | EDICustomer[1]/CreationDate | EDICustomer[1]/CreationTime" />
            </EDICustomer>
        </xsl:if>
        <xsl:for-each-group select="EDICustomer/EDICustomerLine" group-by="(position()-1) idiv $max">
            <EDICustomer>
                <!-- Add a <GroupNr> element with the index of the group -->
                <GroupNr><xsl:value-of select="position()" /></GroupNr>
                <xsl:copy-of select="../Company | ../Customer | ../CreationDate | ../CreationTime" />
                <xsl:copy-of select="current-group()" />
            </EDICustomer>
        </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Результат:

<Root>
    <EDICustomer>
        <GroupNr>1</GroupNr>
        <Company>IWS</Company>
        <Customer>150</Customer>
        <CreationDate>2020-03-15T10:29:08.813</CreationDate>
        <CreationTime>2020-03-15T10:29:08.813</CreationTime>
        <EDICustomerLine>
            <Barcode>447896130245</Barcode>
            <ItemDescription>Medium</ItemDescription>
            <Warehouse>B01</Warehouse>
            <Status>12</Status>
        </EDICustomerLine>
        <EDICustomerLine>
            <Barcode>447896130245</Barcode>
            <ItemDescription>Medium</ItemDescription>
            <Warehouse>B01</Warehouse>
            <Status>12</Status>
        </EDICustomerLine>
        <EDICustomerLine>
            <Barcode>447896130245</Barcode>
            <ItemDescription>Medium</ItemDescription>
            <Warehouse>B01</Warehouse>
            <Status>12</Status>
        </EDICustomerLine>
    </EDICustomer>
    <EDICustomer>
        <GroupNr>2</GroupNr>
        <Company>IWS</Company>
        <Customer>150</Customer>
        <CreationDate>2020-03-15T10:29:08.813</CreationDate>
        <CreationTime>2020-03-15T10:29:08.813</CreationTime>
        <EDICustomerLine>
            <Barcode>447896130245</Barcode>
            <ItemDescription>Medium</ItemDescription>
            <Warehouse>B01</Warehouse>
            <Status>12</Status>
        </EDICustomerLine>
    </EDICustomer>
</Root>

Это по желанию.

...