Как различить два узла с их потомками в строке Tally XML - PullRequest
1 голос
/ 23 апреля 2019

У меня XML такой:

<ENVELOPE>
    <DSPACCNAME>
        <DSPDISPNAME>Opening Stock</DSPDISPNAME>
    </DSPACCNAME>
    <PLAMT>
        <PLSUBAMT/>
        <BSMAINAMT>-44912711.35</BSMAINAMT>
    </PLAMT>
    <BSNAME>
        <DSPACCNAME>
            <DSPDISPNAME>Stock-in-Hand-Accesories(KPM)</DSPDISPNAME>
        </DSPACCNAME>
    </BSNAME>
    <BSAMT>
        <BSSUBAMT>-15750.01</BSSUBAMT>
        <BSMAINAMT/>
    </BSAMT>
    <BSNAME>
        <DSPACCNAME>
            <DSPDISPNAME>Stock-in-Hand-Accesories(KVM)</DSPDISPNAME>
        </DSPACCNAME>
    </BSNAME>
    <BSAMT>
        <BSSUBAMT>-16750.01</BSSUBAMT>
        <BSMAINAMT/>
    </BSAMT>
    <DSPACCNAME>
        <DSPDISPNAME>Closing Stock</DSPDISPNAME>
    </DSPACCNAME>
    <BSNAME>
        <DSPACCNAME>
            <DSPDISPNAME>Stock-in-Hand-Accesories(KPM)</DSPDISPNAME>
        </DSPACCNAME>
    </BSNAME>
    <BSAMT>
        <BSSUBAMT>-54750.01</BSSUBAMT>
        <BSMAINAMT/>
    </BSAMT>
    <BSNAME>
        <DSPACCNAME>
            <DSPDISPNAME>Stock-in-Hand-Accesories(KRM)</DSPDISPNAME>
        </DSPACCNAME>
    </BSNAME>
    <BSAMT>
        <BSSUBAMT>-74750.01</BSSUBAMT>
        <BSMAINAMT/>
    </BSAMT>
</ENVELOPE>

Мой результат должен выглядеть так:

Opening Stock   Stock-in-Hand-Accesories(KPM)   -15750.01
Opening Stock   Stock-in-Hand-Accesories(KVM)   -16750.01
Closing Stock   Stock-in-Hand-Accesories(KPM)   -54750.01
Closing Stock   Stock-in-Hand-Accesories(KRM)   -74750.01

Ответы [ 2 ]

2 голосов
/ 23 апреля 2019

Предполагая, что единственным отношением является порядок узлов, вы можете выбрать все BSNAME узлы в качестве якорей и использовать операторы >> и << для поиска ближайших BSAMT и DSPACCNAME узлов:

DECLARE @xml XML = '<ENVELOPE>
    <DSPACCNAME>
        <DSPDISPNAME>Opening Stock</DSPDISPNAME>
    </DSPACCNAME>
    <PLAMT>
        <PLSUBAMT/>
        <BSMAINAMT>-44912711.35</BSMAINAMT>
    </PLAMT>
    <BSNAME>
        <DSPACCNAME>
            <DSPDISPNAME>Stock-in-Hand-Accesories(KPM)</DSPDISPNAME>
        </DSPACCNAME>
    </BSNAME>
    <BSAMT>
        <BSSUBAMT>-15750.01</BSSUBAMT>
        <BSMAINAMT/>
    </BSAMT>
    <BSNAME>
        <DSPACCNAME>
            <DSPDISPNAME>Stock-in-Hand-Accesories(KVM)</DSPDISPNAME>
        </DSPACCNAME>
    </BSNAME>
    <BSAMT>
        <BSSUBAMT>-16750.01</BSSUBAMT>
        <BSMAINAMT/>
    </BSAMT>
    <DSPACCNAME>
        <DSPDISPNAME>Closing Stock</DSPDISPNAME>
    </DSPACCNAME>
    <BSNAME>
        <DSPACCNAME>
            <DSPDISPNAME>Stock-in-Hand-Accesories(KPM)</DSPDISPNAME>
        </DSPACCNAME>
    </BSNAME>
    <BSAMT>
        <BSSUBAMT>-54750.01</BSSUBAMT>
        <BSMAINAMT/>
    </BSAMT>
    <BSNAME>
        <DSPACCNAME>
            <DSPDISPNAME>Stock-in-Hand-Accesories(KRM)</DSPDISPNAME>
        </DSPACCNAME>
    </BSNAME>
    <BSAMT>
        <BSSUBAMT>-74750.01</BSSUBAMT>
        <BSMAINAMT/>
    </BSAMT>
</ENVELOPE>';
SELECT refnode.value('(./DSPACCNAME/DSPDISPNAME)[1]', 'VARCHAR(100)') AS [BSNAME]
     , refnode.value('let $c := . return (../BSAMT[. >> $c]/BSSUBAMT)[1]', 'DECIMAL(18,2)') AS [BSAMT]
     , refnode.value('let $c := . return (../DSPACCNAME[. << $c]/DSPDISPNAME)[last()]', 'VARCHAR(100)') AS [DSPACCNAME]
FROM @xml.nodes('//ENVELOPE/BSNAME') x(refnode)

Демонстрация по дб <> fiddle

0 голосов
/ 29 апреля 2019

Хотя это было нормально, как предположил Салман А., он очень подвержен ошибкам. Похоже, этот XML был сформирован с помощью специального TDL (надстройка Tally). В этом случае я согласен с Panagiotis Kanavos, что XML не сформирован должным образом. Вы можете попросить разработчика TDL просто переупорядочить теги XML, поместив тег XML на уровне «Line» для каждого родительского узла и на уровне «Field» для каждого дочернего узла. Обратите внимание, что строка должна повторяться с использованием переменной «Repeat», чтобы несколько родительских узлов с дочерними узлами могли появиться в XML.

Вы можете обратиться к этому справочному руководству , в частности к разделу 2.2.5, о том, как использовать теги XML.

...