группировка по неидентичным позициям xsl1.0 - PullRequest
1 голос
/ 04 августа 2020

У меня есть требование, как показано ниже, для реализации преобразования с использованием только XSL1.0,

  1. Первое условие - групповые позиции на основе parentLineNumber .
  2. Затем Второе условие - игнорировать строку счета-фактуры, когда ParentLinenumber и LineNumber одинаковы, только если в группе более одной позиции счета-фактуры.

Пример ввода:

<InvoiceNotification>
    <Invoice>
        <InvoiceLineItem>
            <LineSection>
                <parentLineNumber>000010</parentLineNumber>
            </LineSection>
            <LineNumber>000010</LineNumber>
            <proprietaryInformation>
                <FreeFormText>PK06</FreeFormText>
            </proprietaryInformation>
        </InvoiceLineItem>
        <InvoiceLineItem>
            <LineSection>
                <parentLineNumber>000010</parentLineNumber>
            </LineSection>
            <LineNumber>000011</LineNumber>
            <proprietaryInformation>
                <FreeFormText>PK07</FreeFormText>
            </proprietaryInformation>
        </InvoiceLineItem>
        <InvoiceLineItem>
            <LineSection>
                <parentLineNumber>000010</parentLineNumber>
            </LineSection>
            <LineNumber>000012</LineNumber>
            <proprietaryInformation>
                <FreeFormText>PK08</FreeFormText>
            </proprietaryInformation>
        </InvoiceLineItem>
        <InvoiceLineItem>
            <LineSection>
                <parentLineNumber>000020</parentLineNumber>
            </LineSection>
            <LineNumber>000020</LineNumber>
            <proprietaryInformation>
                <FreeFormText>GK01</FreeFormText>
            </proprietaryInformation>
        </InvoiceLineItem>
    </Invoice>
</InvoiceNotification>

Я разработал ниже XSLT, который частично работает.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:key name="Invoices" match="InvoiceLineItem" use="LineSection/parentLineNumber"/>
    <xsl:template match="InvoiceNotification">
        <Invoices>
            <xsl:for-each select="Invoice/InvoiceLineItem [ count ( key('Invoices',LineSection/parentLineNumber)[1] | . ) = 1 ]">
                <Batchorder>
                    <xsl:for-each select="key('Invoices',LineNumber)">
                        <Items>
                            <LineItem>
                                <xsl:value-of select="proprietaryInformation"/>
                            </LineItem>
                        </Items>
                    </xsl:for-each>
                </Batchorder>
            </xsl:for-each>
        </Invoices>
    </xsl:template>
</xsl:stylesheet>

Результат:

<?xml version="1.0" encoding="UTF-8"?>
<Invoices>
    <Batchorder>
        <Items>
            <proprietaryInformation>PK06</proprietaryInformation>
        </Items>
        <Items>
            <proprietaryInformation>PK07</proprietaryInformation>
        </Items>
        <Items>
            <proprietaryInformation>PK08</proprietaryInformation>
        </Items>
    </Batchorder>
    <Batchorder>
        <Items>
            <proprietaryInformation>GK01</proprietaryInformation>
        </Items>
    </Batchorder>
</Invoices>

Но я ожидаю, что результат будет ниже ,

<?xml version="1.0" encoding="UTF-8"?>
<Invoices>
    <Batchorder>
        <Items>
            <proprietaryInformation>PK07</proprietaryInformation>
        </Items>
        <Items>
            <proprietaryInformation>PK08</proprietaryInformation>
        </Items>
    </Batchorder>
    <Batchorder>
        <Items>
            <proprietaryInformation>GK01</proprietaryInformation>
        </Items>
    </Batchorder>
</Invoices>

Ответы [ 2 ]

1 голос
/ 05 августа 2020

Практически то же решение, что и предложенное Мартином Хонненом, но , вероятно, немного более эффективное :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    <xsl:key name="Invoices" match="InvoiceLineItem" use="LineSection/parentLineNumber"/>
    <xsl:template match="InvoiceNotification">
        <Invoices>
            <xsl:for-each select=
            "Invoice/InvoiceLineItem
            [count ( key('Invoices',LineSection/parentLineNumber)[1] | . ) = 1]">
                <Batchorder>
                    <xsl:for-each select="key('Invoices',LineNumber)
                    [not(LineNumber = LineSection/parentLineNumber)
                    or not(key('Invoices',LineNumber)[2])]">
                        <Items>
                            <LineItem>
                                <xsl:value-of select="proprietaryInformation"/>
                            </LineItem>
                        </Items>
                    </xsl:for-each>
                </Batchorder>
            </xsl:for-each>
        </Invoices>
    </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к предоставленному источнику XML документ :

<InvoiceNotification>
    <Invoice>
        <InvoiceLineItem>
            <LineSection>
                <parentLineNumber>000010</parentLineNumber>
            </LineSection>
            <LineNumber>000010</LineNumber>
            <proprietaryInformation>
                <FreeFormText>PK06</FreeFormText>
            </proprietaryInformation>
        </InvoiceLineItem>
        <InvoiceLineItem>
            <LineSection>
                <parentLineNumber>000010</parentLineNumber>
            </LineSection>
            <LineNumber>000011</LineNumber>
            <proprietaryInformation>
                <FreeFormText>PK07</FreeFormText>
            </proprietaryInformation>
        </InvoiceLineItem>
        <InvoiceLineItem>
            <LineSection>
                <parentLineNumber>000010</parentLineNumber>
            </LineSection>
            <LineNumber>000012</LineNumber>
            <proprietaryInformation>
                <FreeFormText>PK08</FreeFormText>
            </proprietaryInformation>
        </InvoiceLineItem>
        <InvoiceLineItem>
            <LineSection>
                <parentLineNumber>000020</parentLineNumber>
            </LineSection>
            <LineNumber>000020</LineNumber>
            <proprietaryInformation>
                <FreeFormText>GK01</FreeFormText>
            </proprietaryInformation>
        </InvoiceLineItem>
    </Invoice>
</InvoiceNotification>

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

<Invoices>
   <Batchorder>
      <Items>
         <LineItem>
                PK07
            </LineItem>
      </Items>
      <Items>
         <LineItem>
                PK08
            </LineItem>
      </Items>
   </Batchorder>
   <Batchorder>
      <Items>
         <LineItem>
                GK01
            </LineItem>
      </Items>
   </Batchorder>
</Invoices>
1 голос
/ 04 августа 2020

Вы можете использовать предикат для for-each Я думаю:

<xsl:for-each select="key('Invoices',LineNumber)[LineNumber != LineSection/parentLineNumber or count(key('Invoices', LineNumber)) = 1]">
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...