如何解析数据库中一列中 Xml 文件的不同根目录?
How to parse different roots from Xml file in one column in database?
我正在尝试解析存储的 procedure.How 中的 Xml 文件,以将不同的根解析为数据库中的 CustomFields(具有 xml 类型的列的名称)?我想要不同的为 CustomFields 列提供根。
我在数据库中有一个table:
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 | ... |
所需的输出阐明了 objective。
每个 <offer>
元素有 2 种类型的子元素:
- 要转换成矩形数据的标准元素集
设置。
- 要保留的剩余动态元素集为XML。
CustomFields 列,XML 数据类型,应包含未分解和转换为 rectangular/relational 数据的剩余 XML 元素设置。
假定每个 <offer>
元素的 id
属性值是唯一的。
请参阅 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;
Output
+----+-------------+-------+-------------------------------------------------------------------------------------------------------------------------+
| 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> |
+----+-------------+-------+-------------------------------------------------------------------------------------------------------------------------+
我正在尝试解析存储的 procedure.How 中的 Xml 文件,以将不同的根解析为数据库中的 CustomFields(具有 xml 类型的列的名称)?我想要不同的为 CustomFields 列提供根。
我在数据库中有一个table:
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 | ... |
所需的输出阐明了 objective。
每个 <offer>
元素有 2 种类型的子元素:
- 要转换成矩形数据的标准元素集 设置。
- 要保留的剩余动态元素集为XML。
CustomFields 列,XML 数据类型,应包含未分解和转换为 rectangular/relational 数据的剩余 XML 元素设置。
假定每个 <offer>
元素的 id
属性值是唯一的。
请参阅 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;
Output
+----+-------------+-------+-------------------------------------------------------------------------------------------------------------------------+
| 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> |
+----+-------------+-------+-------------------------------------------------------------------------------------------------------------------------+