У меня 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
Не уверен, что понимаю. Значение BSSUBAMT и DSPDISPNAME не связаны в этом XML; они не находятся в одном узле. Если они связаны, они должны иметь общий родительский узел (это не корневая заметка).
Почему Opening Stock должно быть связано с -15750.01 вместо -54750.01? Есть ничего, который говорит, что они связаны. Если этот Envelope должен содержать две записи, я бы сказал, что дизайн очень плохой и его нужно исправить.
Здесь нет «но это то, что у меня есть», в XML эти элементы не имеют ничего общего, кроме корневого элемента. Их порядок или тот факт, что они повторяются, не считается. Это не то, как должен работать XML.
Всегда ли будет присутствовать узел PLAMT?
Этот нить потребуется преобразовать, прежде чем его можно будет рассматривать как XML. Например, вы можете заменить <DSPACCNAME> на <record><DSPACCNAME> и </BSAMT> на </BSAMT></record>, чтобы преобразовать строку в разборчивый XML.
Возможно, если бы ваш XML был больше похож на это, было бы проще. :/
Вы пытаетесь работать с счет? В этом случае вы должны четко указать, что могут быть другие, которые нашли способ работать с этим продуктом и .... своеобразным синтаксисом XML. Это также дало бы понять, что автор строки не собирается ее исправлять.


Предполагая, что единственным отношением является порядок узлов, вы можете выбрать все узлы 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)
Учитывая, что узлы верхнего уровня также появляются под дочерними узлами, порядок, вероятно, является единственным способом анализа этого.
Я боюсь, что этот нить на самом деле является представлением какого-то поставщика ERP о том, как должен выглядеть формат экспорта XML. Что касается их SOAP API ....
Это нормально, но мне нужны данные на основе BSNAME, а не в смысле DSPACCNAME.
Хотя это можно было сделать, как предложил Салман А., это очень подвержено ошибкам. Похоже, этот XML был сформирован с помощью пользовательского TDL (надстройки Tally). В этом случае я согласен с Панайотисом Канавосом в том, что XML сформирован неправильно. Вы можете попросить разработчика TDL просто переупорядочить теги XML, поместив тег XML на уровень «Строка» для каждого родительского узла и на уровень «Поле» для каждого дочернего узла. Обратите внимание, что строка должна повторяться с использованием переменной «Повторить» для нескольких родительских узлов с дочерними узлами, которые появляются в XML.
Вы можете обратиться к этому справочник, в частности к разделу 2.2.5, о том, как использовать теги XML.
Это столбец XML или переменная XML?