Как разобрать разные корни из Xml файла в одном столбце базы данных? - PullRequest
1 голос
/ 13 июля 2020

Я пытаюсь выполнить синтаксический анализ файла Xml в хранимой процедуре. Как выполнить синтаксический анализ различных корней в CustomFields (имя столбца с типом xml) в базе данных? Я хочу получить разные корни предложений для столбца CustomFields.

У меня в базе есть таблица:

CREATE TABLE Offers(
Id INT PRIMARY KEY,
Url NVARCHAR(50),
Price INT,

CustomFields xml);

XMl файл:

<?xml version="1.0" standalone="yes" ?>
<offers>
    <offer id="1" type="model" >
        <url>http://....</url>
        <price>1500</price>
                
        <vendor>НP</vendor>
        <vendorCode>Q7533A</vendorCode>
        <model>Color LaserJet 3000</model>
    </offer>

    <offer id="2" type="book" >
        <url>http://...</url>
        <price>100</price>

        <author>Tom</author>
        <name>Name</name>
        <year>2009</year>
        <language>eng</language>
    </offer>
</offers>

Хранимая процедура:

CREATE PROCEDURE AddOffer
    @XmlDocument XML
AS
BEGIN

    SET NOCOUNT ON;

    INSERT INTO Offers

    SELECT 
    offer.value('@id','INT') AS Id,
    offer.value('(url/text())[1]','NVARCHAR(50)') AS Url,
    offer.value('(price)[1]','INT') AS Price,
    How to parse in CustomFields??
    
    FROM
    @XmlDocument.nodes('//offers/offer')AS TEMPTABLE(offer)

END

Пример:

Id   |  Url         | Price  |CategoryId |   Picture        | Delivery |        CustomFields           |
1    |http://...    |  1500  |     1     |  http://...      |    1     |  Other XML offer without      |
                                                                       |  Url,Price,CategoryId ,Picture| 
     
2    |http://...    |  100   |     2     |  http://...      |    1     |             ...               |

1 Ответ

1 голос
/ 13 июля 2020

Желаемый результат проясняет цель.

Каждый элемент <offer> имеет 2 типа дочерних элементов:

  1. Стандартный набор элементов, которые нужно преобразовать в прямоугольник angular набор данных.
  2. Оставшийся динамический c набор элементов, который будет сохранен как XML.

Столбец CustomFields , XML тип данных , должен содержать оставшиеся XML элементов, которые не были измельчены и преобразованы в прямоугольный / реляционный набор данных.

Предполагается, что значение атрибута id уникально для каждого элемента <offer>.

См. Дополнительные комментарии к деталям реализации внутри T- SQL.

SQL

DECLARE @XmlDocument XML = 
N'<?xml version="1.0"?>
<offers>
    <offer id="1" type="model">
        <url>http://....</url>
        <price>1500</price>

        <vendor>НP</vendor>
        <vendorCode>Q7533A</vendorCode>
        <model>Color LaserJet 3000</model>
    </offer>
    <offer id="2" type="book">
        <url>http://...</url>
        <price>100</price>

        <author>Tom</author>
        <name>Name</name>
        <year>2009</year>
        <language>eng</language>
    </offer>
</offers>';

/*
(1) We are using CROSS APPLY to get the XML's values into a result set as normal columns.
In our case they are offer.OfferId and offer.OfferType
(2) These columns are passed into XQuery by using sql:column().
(3) The XQuery FLWOR expression filters out not needed elements that were shredded.
*/
-- INSERT INTO Offers (Id, Url, Price, CustomFields)
SELECT c.value('@id','INT') AS id
    , c.value('(url/text())[1]','NVARCHAR(50)') AS Url
    , c.value('(price/text())[1]','INT') AS Price
    --, offer.OfferId
    , @XmlDocument.query('<offer id="{sql:column("offer.OfferId")}" type="{sql:column("offer.OfferType")}">
    {
        for $x in /offers/offer[@id=sql:column("offer.OfferId")]/*[not(local-name(.) = ("url", "price","CategoryId","Picture"))]
        return $x
    }
    </offer>') AS CustomFields 
FROM @XmlDocument.nodes('/offers/offer')AS t(c)
    CROSS APPLY (SELECT t.c.value('@id','INT') AS OfferId
                        , t.c.value('@type','VARCHAR(30)') AS OfferType
         ) AS offer;

Вывод

+----+-------------+-------+-------------------------------------------------------------------------------------------------------------------------+
| id |     Url     | Price |                                                      CustomFields                                                       |
+----+-------------+-------+-------------------------------------------------------------------------------------------------------------------------+
|  1 | http://.... |  1500 | <offer id="1" type="model"><vendor>НP</vendor><vendorCode>Q7533A</vendorCode><model>Color LaserJet 3000</model></offer> |
|  2 | http://...  |   100 | <offer id="2" type="book"><author>Tom</author><name>Name</name><year>2009</year><language>eng</language></offer>        |
+----+-------------+-------+-------------------------------------------------------------------------------------------------------------------------+
...