问题
I have XML stored into database with the different tag names but the same attribute names:
<book Category="Hobbies And Interests" PropertyName="C#" CategoryID="44" />
<sport Category="Hobbies And Interests" PropertyName="Cricket" CategoryID="46" />
These are just two examples but the tag name can be anything. I want to read "PropertyName" attribute from all node.
Is it possible? If yes then please anyone guide me.
回答1:
declare @xml xml
set @xml = '<book Category="Hobbies And Interests" PropertyName="C#" CategoryID="44" />
<sport Category="Hobbies And Interests" PropertyName="Cricket" CategoryID="46" />'
select T.c.value('@PropertyName', 'varchar(100)')
from @xml.nodes('/*') T(c)
If you expect that there can be elements without PropertyName attribute, you can use:
select T.c.value('@PropertyName', 'varchar(100)')
from @xml.nodes('/*[@PropertyName]') T(c)
If you also expect that elements can be nested, you can use:
select T.c.value('@PropertyName', 'varchar(100)')
from @xml.nodes('//*[@PropertyName]') T(c)
回答2:
Try this solution if you want to read PropertyName
values from all nodes:
DECLARE @MyTable TABLE(
ID INT IDENTITY(1,1) PRIMARY KEY,
XmlCol XML NOT NULL
);
INSERT @MyTable(XmlCol)
VALUES (N'<book Category="Hobbies And Interests" PropertyName="C#" CategoryID="44" />');
INSERT @MyTable(XmlCol)
VALUES (N'<sport Category="Hobbies And Interests" PropertyName="Cricket" CategoryID="46" />');
INSERT @MyTable(XmlCol)
VALUES (N'<CocoJambo PropertyName="Aircraft carrier" Category="Hobbies And Interests"> <CocoJamboChild PropertyName="Airplane"/> </CocoJambo>');
INSERT @MyTable(XmlCol)
VALUES (N'<sport CategoryID="CocoJamboID" />');
SELECT a.*,
b.Node.value('(.)','NVARCHAR(100)') AS PropertyName_Value
FROM @MyTable a
-- OUTER APPLY or CROSS APLLY
OUTER APPLY a.XmlCol.nodes('//@*[local-name(.)="PropertyName"]') b(Node);
Results:
ID XmlCol PropertyName_Value
----------- ----------------------------------------- ------------------
1 <book Category="Hobbies And Interes ... C#
2 <sport Category="Hobbies And Intere ... Cricket
3 <CocoJambo PropertyName="Aircraft c ... Aircraft carrier
3 <CocoJambo PropertyName="Aircraft c ... Airplane
4 <sport CategoryID="CocoJamboID" /> NULL
But if you want to show all rows that have XML framents with at least one PropertyName
attribute then you could try:
SELECT a.*
FROM @MyTable a
WHERE a.XmlCol.exist('//@*[local-name(.)="PropertyName"]')=1;
Results:
ID XmlCol
----------- ----------------------------------------------------------------------------------
1 <book Category="Hobbies And Interests" PropertyName="C#" CategoryID="44" />
2 <sport Category="Hobbies And Interests" PropertyName="Cricket" CategoryID="46" />
3 <CocoJambo PropertyName="Aircraft carrier" Category="Hobbies And Interests"><CocoJ ...
来源:https://stackoverflow.com/questions/17857468/read-xml-node-attributes-without-using-node-name-in-sql-server-query