Выберите оператор на основе атрибутов в xml записей как varchar в SQL Server - PullRequest
0 голосов
/ 20 января 2020

У меня есть таблица с 2 столбцами, ID (Int) и ResponseData (Varchar(MAX)), в которой я сохранил XML текст, как показано здесь:

<?xml version="1.0" encoding="UTF-8"?>
<soapTest:Response xmlns:soapTest="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xs="http://www.w3.org/2001/XMLSchema" Version="2.0">
   <soap:Issuer xmlns:soap="urn:oasis:names:tc:SAML:2.0:assertion">https://abc.sa/</soap:Issuer>
   <soapTest:Status>
      <soapTest:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
   </soapTest:Status>
   <soap:Assertion xmlns:soap="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0">
      <soap:AttributeStatement>
         <soap:Attribute Name="http://abc/xxx/englishFirstName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
            <soap:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">JACK</soap:AttributeValue>
         </soap:Attribute>
     <soap:Attribute Name="http://abc/xxx/englishName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
            <soap:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Jack Mike</soap:AttributeValue>
         </soap:Attribute>
         <soap:Attribute Name="http://abc/xxx/lang" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
            <soap:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">en</soap:AttributeValue>
         </soap:Attribute>
         <soap:Attribute Name="http://abc/xxx/dob" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
            <soap:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Thu Jan 21 00:00:00 AST 1988</soap:AttributeValue>
         </soap:Attribute>
         <soap:Attribute Name="http://abc/xxx/userid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
            <soap:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1010026175</soap:AttributeValue>
         </soap:Attribute>
         <soap:Attribute Name="http://abc/xxx/nationality" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
            <soap:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Canadian</soap:AttributeValue>
         </soap:Attribute>
         <soap:Attribute Name="http://abc/xxx/englishGrandFatherName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
            <soap:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">test</soap:AttributeValue>
         </soap:Attribute>
      </soap:AttributeStatement>
   </soap:Assertion>
</soapTest:Response>

Теперь у меня более 100 записей в таблице, у некоторых записей ответа / xml нет тега / узла "Атрибут" с атрибутом "Имя = http://abc/xxx/englishName", как я могу вернуть все эти записи, которые не имеют есть этот узел?

Например

Первая запись имеет тег / атрибут ниже:

<soap:Attribute Name="http://abc/xxx/englishName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
 <soap:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Jack Mike</soap:AttributeValue>
     </soap:Attribute>

Вторая запись не имеет его, ответ пришел без атрибута Имя englishName ...

Я хочу вернуть все записи с их идентификатором, чтобы узнать, у кого нет этого атрибута, результат будет

ID                    responseData
---------------------------------------------------------------
12                    <?xml version="1.0" encodxxxxxxxx
15                    <?xml version="1.0" encodxxxxxxxx
87                    <?xml version="1.0" encodxxxxxxxx

1 Ответ

1 голос
/ 20 января 2020

Исходя из неопределенных требований, попробуйте следующее.

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY(1,1) PRIMARY KEY, ResponseData NVARCHAR(MAX));
INSERT INTO @tbl
VALUES (N'<soapTest:Response xmlns:soapTest="urn:oasis:names:tc:SAML:2.0:protocol"
                   xmlns:xs="http://www.w3.org/2001/XMLSchema" Version="2.0">
    <soap:Issuer xmlns:soap="urn:oasis:names:tc:SAML:2.0:assertion">https://abc.sa/</soap:Issuer>
    <soapTest:Status>
        <soapTest:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
    </soapTest:Status>
    <soap:Assertion xmlns:soap="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0">
        <soap:AttributeStatement>
            <soap:Attribute Name="http://abc/xxx/englishFirstName"
                            NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <soap:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                     xsi:type="xs:string">JACK</soap:AttributeValue>
            </soap:Attribute>
            <soap:Attribute Name="http://abc/xxx/englishName"
                            NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <soap:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                     xsi:type="xs:string">Jack Mike</soap:AttributeValue>
            </soap:Attribute>
            <soap:Attribute Name="http://abc/xxx/lang"
                            NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <soap:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                     xsi:type="xs:string">en</soap:AttributeValue>
            </soap:Attribute>
            <soap:Attribute Name="http://abc/xxx/dob"
                            NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <soap:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                     xsi:type="xs:string">Thu Jan 21 00:00:00 AST 1988</soap:AttributeValue>
            </soap:Attribute>
            <soap:Attribute Name="http://abc/xxx/userid"
                            NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <soap:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                     xsi:type="xs:string">1010026175</soap:AttributeValue>
            </soap:Attribute>
            <soap:Attribute Name="http://abc/xxx/nationality"
                            NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <soap:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                     xsi:type="xs:string">Canadian</soap:AttributeValue>
            </soap:Attribute>
            <soap:Attribute Name="http://abc/xxx/englishGrandFatherName"
                            NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <soap:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                     xsi:type="xs:string">test</soap:AttributeValue>
            </soap:Attribute>
        </soap:AttributeStatement>
    </soap:Assertion>
</soapTest:Response>');
-- DDL and sample data population, end

;WITH XMLNAMESPACES(DEFAULT 'urn:oasis:names:tc:SAML:2.0:assertion'
    , 'urn:oasis:names:tc:SAML:2.0:protocol' AS [soapTest]), rs AS
(
   SELECT *, TRY_CAST(ResponseData AS XML) AS [xml_data]
   FROM @tbl
)
SELECT ID
    , col.query('.') AS [xml_data]
FROM rs AS tbl
    CROSS APPLY tbl.[xml_data].nodes('/soapTest:Response') AS tab(col)
WHERE col.exist('Assertion/AttributeStatement/Attribute/@Name[.="http://abc/xxx/englishName"]') = 0;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...