XML Xquery 如何删除特定字符前的字符串?

XML Xquery How to remove string before a specific character?

我正在尝试替换 xquery 中元素的部分数据。

在我的数据库(Sql Server 2017)中,我有一个 table,其中包含一千个 XML。

请在下面找到我的 XML

的一个示例
<Policies>
    <Policy>
        <GroupUserName>WERD\AA12BB34</GroupUserName>
        <GroupUserId>AQUAAAAAAAUVAAAAMAdSpoMScJXq9mQyj30AAA==</GroupUserId>
        <Roles>
            <Role>
                <Name>Role 1</Name>
                <Description>Enter description.</Description>
            </Role>
            <Role>
                <Name>Role 2</Name>
                <Description>Enter description.</Description>
            </Role>
            <Role>
                <Name>Role 3</Name>
                <Description>Enter description.</Description>
            </Role>
            <Role>
                <Name>Role 4</Name>
                <Description>Enter description
            </Role>
            <Role>
                <Name>Role 5</Name>
                <Description>Enter description.</Description>
            </Role>
        </Roles>
    </Policy>
    <Policy>
        <GroupUserName>NTKD0\BB159FFN</GroupUserName>
        <GroupUserId>AQUAAAAAAAUVAAAALZBmswQnK326hQEyvt0JAA==</GroupUserId>
        <Roles>
            <Role>
                <Name>Role 1</Name>
                <Description>Enter description.</Description>
            </Role>
        </Roles>
    </Policy>
</Policies>

重点关注这部分 我需要删除此“\”之前的所有字符

<GroupUserName>WERD\AA12BB34</GroupUserName>
<GroupUserName>NTKD0\BB159FFN</GroupUserName>

预计

<GroupUserName>AA12BB34</GroupUserName>
<GroupUserName>BB159FFN</GroupUserName>

到目前为止我已经完成了:

SELECT XmlDescription,
    replace(CAST(XmlDescription AS VARCHAR(8000)),'<GroupUserName>WERD\','<GroupUserName>')
from xml_temp 
WHERE ID = 1;

我也试过:

replace(CAST(XmlDescription AS VARCHAR(8000)), '^.*\', '')

但什么也没发生....

在sql我曾经做过:

REPLACE(SUBSTRING(myField, CHARINDEX('\', myField), LEN(myField)), '\', '')

我正在尝试使用 xquery 实现此方法

你能帮帮我吗?

此致,

create table dbo.xml_temp (
    ID [uniqueidentifier] NOT NULL,
    XmlDescription xml not null
);
insert into dbo.xml_temp (ID,XmlDescription) values (NEWID(),'<Policies>
    <Policy>
        <GroupUserName>WERD\AA12BB34</GroupUserName>
        <GroupUserId>AQUAAAAAAAUVAAAAMAdSpoMScJXq9mQyj30AAA==</GroupUserId>
        <Roles>
            <Role>
                <Name>Role 1</Name>
                <Description>Enter description.</Description>
            </Role>         
        </Roles>
    </Policy>
    <Policy>
        <GroupUserName>NTKD0\BB159FFN</GroupUserName>
        <GroupUserId>AQUAAAAAAAUVAAAALZBmswQnK326hQEyvt0JAA==</GroupUserId>
        <Roles>
            <Role>
                <Name>Role 1</Name>
                <Description>Enter description.</Description>
            </Role>
        </Roles>
    </Policy>
</Policies>')
SELECT @@version

微软 SQL 服务器 2017 (RTM)

请尝试以下解决方案。

这是一个解决方法(kludge),因为 SQL Server XQuery 甚至不完全支持 XQuery v.1.0

在我们的例子中,缺少 substring-after() 函数。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmldata XML);
INSERT INTO @tbl (xmldata) VALUES
(N'<Policies>
    <Policy>
        <GroupUserName>WERD\AA12BB34</GroupUserName>
        <GroupUserId>AQUAAAAAAAUVAAAAMAdSpoMScJXq9mQyj30AAA==</GroupUserId>
        <Roles>
            <Role>
                <Name>Role 1</Name>
                <Description>Enter description.</Description>
            </Role>
            <Role>
                <Name>Role 2</Name>
                <Description>Enter description.</Description>
            </Role>
        </Roles>
    </Policy>
    <Policy>
        <GroupUserName>NTKD0\BB159FFN</GroupUserName>
        <GroupUserId>AQUAAAAAAAUVAAAALZBmswQnK326hQEyvt0JAA==</GroupUserId>
        <Roles>
            <Role>
                <Name>Role 1</Name>
                <Description>Enter description.</Description>
            </Role>
        </Roles>
    </Policy>
</Policies>');
-- DDL and sample data population, end

SELECT * 
, xmldata.query('<Policies>
{
    for $x in /Policies/Policy
    return <Policy>
        <GroupUserName>{
          if (contains(($x/GroupUserName/text())[1],"WERD")) then substring(($x/GroupUserName/text())[1],6,100)
          else substring(($x/GroupUserName/text())[1],7,100)
        }
        </GroupUserName>
        {$x/*[local-name()!="GroupUserName"]}
    </Policy>
}
</Policies>') AS Result
FROM @tbl;