Bạn có thể thực hiện điều này một cách rõ ràng với XQuery và một CTE đệ quy (không có OPENXML
):
DECLARE @xml xml
SET @xml = '<a><b /><c><d /><d /><d /></c></a>';
WITH Xml_CTE AS
(
SELECT
CAST('/' + node.value('fn:local-name(.)',
'varchar(100)') AS varchar(100)) AS name,
node.query('*') AS children
FROM @xml.nodes('/*') AS roots(node)
UNION ALL
SELECT
CAST(x.name + '/' +
node.value('fn:local-name(.)', 'varchar(100)') AS varchar(100)),
node.query('*') AS children
FROM Xml_CTE x
CROSS APPLY x.children.nodes('*') AS child(node)
)
SELECT DISTINCT name
FROM Xml_CTE
OPTION (MAXRECURSION 1000)
Nó không thực sự làm được nhiều điều kỳ diệu của XQuery, nhưng ít nhất tất cả đều là nội tuyến, không yêu cầu bất kỳ thủ tục lưu trữ nào, các quyền đặc biệt, v.v.