SQL Сервер: выберите атрибут из xml, где имя атрибута определяется пространством имен - PullRequest
0 голосов
/ 05 февраля 2020

Я не смог ничего найти конкретно по этому вопросу, но мне хотелось бы знать, как я могу выбрать атрибут подузла в XML, который идентифицируется пространством имен, asp для пространства имен XLINK ниже:

<?xml version="1.0" encoding="UTF-8"?>
<result xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink">
  <people lastUpdateDate="xxxx-xx-xx">
    <person name="Paul" surname="Who Cares" height="180" weight="89" xlink:href="https://i.stack.imgur.com/jMgYU.jpg?s=48&g=1" />
  </people>
</result>

В настоящее время мой запрос выглядит следующим образом, но мне просто нужно внести небольшое изменение, чтобы получить ссылку.

DECLARE @xml AS TABLE(MyXml xml);

INSERT @xml SELECT CONVERT(xml, BulkColumn, 2) 
FROM OPENROWSET (Bulk '[filepath]', SINGLE_BLOB) [rowsetresults];

WITH xmlnamespaces('http://www.w3.org/1999/xlink' AS a)
SELECT
      Person.value('@name', 'NVARCHAR(50)'),
      Person.value('@surname', 'NVARCHAR(50)'),
      Person.value('@height', 'INT'),
      Person.value('@weight', 'INT'),
      Person.value('@xlink:href', 'NVARCHAR(500)'), -- THIS IS WHERE I NEED HELP
FROM
    @xml
    CROSS APPLY [MyXml].nodes('result/people')    AS MyXml(People)
    OUTER APPLY People.nodes('person')              AS People(Person); 

Ответы [ 2 ]

0 голосов
/ 05 февраля 2020

Несколько замечаний. (1) Ссылка имеет амперсанд. Одиночный символ & запрещен в XML, кроме раздела CDATA. Поэтому я заменил его на &amp;, он же амперсанд, чтобы сделать XML правильно сформированным. (2) У XML есть пара пространств имен, поэтому вам нужно указать их в T- SQL. В этом случае требуется только одно пространство имен. (3) Нет необходимости использовать несколько предложений CROSS APPLY/OUTER APPLY.

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmldata XML);
INSERT INTO @tbl (xmldata) VALUES
('<?xml version="1.0" encoding="UTF-8"?>
<result xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xlink="http://www.w3.org/1999/xlink">
    <people lastUpdateDate="xxxx-xx-xx">
        <person name="Paul" surname="Who Cares" height="180" weight="89"
                xlink:href="https://i.stack.imgur.com/jMgYU.jpg?s=48&amp;g=1"/>
    </people>
</result>');
-- DDL and sample data population, end

;WITH XMLNAMESPACES ('http://www.w3.org/1999/xlink' AS xlink)
SELECT c.value('@name', 'NVARCHAR(50)') AS [Name]
    , c.value('@surname', 'NVARCHAR(50)') AS [Surname]
    , c.value('@height', 'INT') AS [Height]
    , c.value('@weight', 'INT') AS [Weight]
    , c.value('@xlink:href', 'NVARCHAR(500)') AS [URL]
FROM @tbl AS tbl
    CROSS APPLY tbl.xmldata.nodes('/result/people/person') AS t(c);

Вывод

+------+-----------+--------+--------+----------------------------------------------+
| Name |  Surname  | Height | Weight |                     URL                      |
+------+-----------+--------+--------+----------------------------------------------+
| Paul | Who Cares |    180 |     89 | https://i.stack.imgur.com/jMgYU.jpg?s=48&g=1 |
+------+-----------+--------+--------+----------------------------------------------+
0 голосов
/ 05 февраля 2020

Заменить xlink: href на xlinkhref

DECLARE @xml AS TABLE(MyXml xml);

INSERT into @xml values('<?xml version="1.0" encoding="UTF-8"?>
<result xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink">
  <people lastUpdateDate="xxxx-xx-xx">
    <person name="Paul" surname="Who Cares" height="180" weight="89" xlink:href="https://i.stack.imgur.com/jMgYU.jpg?s=48&amp;g=1" />
  </people>
</result>')

UPDATE @xml set MyXml=REPLACE(CONVERT(NVARCHAR(MAX),(MyXml)),'xlink:href','xlinkhref')

SELECT
      Person.value('@name', 'NVARCHAR(50)'),
      Person.value('@surname', 'NVARCHAR(50)'),
      Person.value('@height', 'INT'),
      Person.value('@weight', 'INT'),
      Person.value('@xlinkhref', 'NVARCHAR(500)') -- THIS IS WHERE I NEED HELP
FROM
    @xml
    CROSS APPLY [MyXml].nodes('result/people')    AS MyXml(People)
    OUTER APPLY People.nodes('person')              AS People(Person); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...