SQL 服务器 - XQuery:根据子值子字符串删除父节点

SQL Server - XQuery: delete parent node based on child value substring

我想删除以下XML的所有父节点TxDtls,其中子值Ref的位置20是2。

<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.054.001.04" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:camt.054.001.04 camt.054.001.04.xsd">
  <BkToCstmrDbtCdtNtfctn>
    <Ntfctn>
      <Ntry>
          <TtlChrgsAndTaxAmt Ccy="CHF">1.60</TtlChrgsAndTaxAmt>
          <Rcrd>
            <Amt Ccy="CHF">1.60</Amt>
            <CdtDbtInd>DBIT</CdtDbtInd>
            <ChrgInclInd>false</ChrgInclInd>
            <Tp>
              <Prtry>
                <Id>2</Id>
              </Prtry>
            </Tp>
          </Rcrd>
        </Chrgs>
        <NtryDtls>
           <TxDtls>
            <RmtInf>
              <Strd>
                <CdtrRefInf>
                  <Ref>111118144400000000020076766</Ref>
                </CdtrRefInf>
               </Strd>
            </RmtInf>
           </TxDtls>
          <TxDtls>
             <RmtInf>
              <Strd>
                <CdtrRefInf>
                  <Ref>111117645600000000030076281</Ref>
                </CdtrRefInf>
              </Strd>
            </RmtInf>
          </TxDtls>
        </NtryDtls>
      </Ntry>
    </Ntfctn>
  </BkToCstmrDbtCdtNtfctn>
</Document>

所以我想删除第一个 TxDtls 节点(子字符串位置 20 = 2),同时我想保留第二个节点(子字符串位置 20 <> 2)。

我试过这个:

UPDATE mytable SET XMLData.modify('delete .//TxDtls[RmtInf/Strd/CdtrRefInf/Ref/substring(text(),20,1) = ''2'']')

但是,我收到错误消息“不支持 XQuery 语法‘/function()’”。关于如何实现这一目标的任何提示?

谢谢

部分提供的最小可重现示例

有什么不同

XML 的格式仍然不正确。我不得不注释掉以下标签:</Chrgs>

默认命名空间很容易通过其在 XQuery 方法中的声明来处理。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmldata XML);
INSERT INTO @tbl (xmldata) VALUES
(N'<?xml version="1.0"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.054.001.04"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:camt.054.001.04 camt.054.001.04.xsd">
    <BkToCstmrDbtCdtNtfctn>
        <Ntfctn>
            <Ntry>
                <TtlChrgsAndTaxAmt Ccy="CHF">1.60</TtlChrgsAndTaxAmt>
                <Rcrd>
                    <Amt Ccy="CHF">1.60</Amt>
                    <CdtDbtInd>DBIT</CdtDbtInd>
                    <ChrgInclInd>false</ChrgInclInd>
                    <Tp>
                        <Prtry>
                            <Id>2</Id>
                        </Prtry>
                    </Tp>
                </Rcrd>
                <!--</Chrgs>-->
                <NtryDtls>
                    <TxDtls>
                        <RmtInf>
                            <Strd>
                                <CdtrRefInf>
                                    <Ref>111118144400000000020076766</Ref>
                                </CdtrRefInf>
                            </Strd>
                        </RmtInf>
                    </TxDtls>
                    <TxDtls>
                        <RmtInf>
                            <Strd>
                                <CdtrRefInf>
                                    <Ref>111117645600000000030076281</Ref>
                                </CdtrRefInf>
                            </Strd>
                        </RmtInf>
                    </TxDtls>
                </NtryDtls>
            </Ntry>
        </Ntfctn>
    </BkToCstmrDbtCdtNtfctn>
</Document>');
-- DDL and sample data population, end

-- before
SELECT * FROM @tbl;

UPDATE @tbl SET xmldata.modify('declare default element namespace "urn:iso:std:iso:20022:tech:xsd:camt.054.001.04";
delete /Document/BkToCstmrDbtCdtNtfctn/Ntfctn/Ntry/NtryDtls/TxDtls[RmtInf/Strd/CdtrRefInf/Ref[substring(./text()[1],20,1) = "2"]]');

-- after
SELECT * FROM @tbl;