我的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
答案 0 :(得分:2)
假设唯一的关系是节点的顺序,则可以选择所有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)
答案 1 :(得分:0)
尽管可以按Salman A的建议进行操作,但它很容易出错。看起来此XML是由自定义TDL(Tally附加组件)组成的。在这种情况下,我同意Panagiotis Kanavos的观点,即XML格式不正确。您可以让TDL开发人员简单地重新排列XML标签,方法是将XML标签放置在每个父节点的“行”级别,并将每个子节点放置在“字段”级。请注意,必须使用'Repeat'变量来重复行,以使多个带有子节点的父节点出现在XML中。
您可以参考reference guide,特别是有关如何使用XML标签的第2.2.5节。