How to get data from XML file to SQL query, following code is not working.
<FVDL>
<EngineData>
<RuleInfo>
<Rule id="13EFF385-69A9-494A-9C67-951FEDAB25ED">
<MetaInfo>
<Group name="package">Python Core xml</Group>
<Group name="inputsource">XML Document</Group>
<Group name="audience">broad</Group>
</MetaInfo>
</Rule>
<Rule id="E9DB1C0E-025E-4EBF-A804-6C3DA413E652">
<MetaInfo>
<Group name="altcategoryMIS">Python Core zipfile</Group>
<Group name="altcategoryGDPR">Access Violation</Group>
</MetaInfo>
</Rule>
</RuleInfo>
</EngineData>
</FVDL>
USE OPENXMLTesting
GO
DECLARE @XML AS XML, @hDoc AS INT
SELECT @XML = XMLData FROM XMLwithOpenXML
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML
Select ID, name, [Group]
FROM OPENXML(@hDoc, 'FVDL/EngineData/RuleInfo')
WITH
(
ID [varchar](100) 'Rule/@id',
[name] [varchar](100) 'Rule/MetaInfo/Group/@name',
[Group] [varchar](1000) 'MetaInfo/Group/.. '
)
EXEC sp_xml_removedocument @hDoc
Looking for result like this
ID | Name | Group |
---|---|---|
13EFF385-69A9-494A-9C67-951FEDAB25ED | package | Python Core xml |
13EFF385-69A9-494A-9C67-951FEDAB25ED | nputsource | XML Document |
13EFF385-69A9-494A-9C67-951FEDAB25ED | audience | broad |
E9DB1C0E-025E-4EBF-A804-6C3DA413E652 | altcategoryMIS | Python Core zipfile |
E9DB1C0E-025E-4EBF-A804-6C3DA413E652 | altcategoryGDPR | Access Violation |
CodePudding user response:
Please try the following solution.
Starting from SQL Server 2005 onwards, it is better to use XQuery language, based on the w3c standards, while dealing with the XML data type.
Microsoft proprietary OPENXML
and its companions sp_xml_preparedocument
and sp_xml_removedocument
are kept just for backward compatibility with the obsolete SQL
Server 2000. Their use is diminished just to very few fringe cases.
It is strongly recommended to re-write your SQL and switch it to XQuery.
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmldata XML);
INSERT INTO @tbl (xmldata) VALUES
(N'<FVDL>
<EngineData>
<RuleInfo>
<Rule id="13EFF385-69A9-494A-9C67-951FEDAB25ED">
<MetaInfo>
<Group name="package">Python Core xml</Group>
<Group name="inputsource">XML Document</Group>
<Group name="audience">broad</Group>
</MetaInfo>
</Rule>
<Rule id="E9DB1C0E-025E-4EBF-A804-6C3DA413E652">
<MetaInfo>
<Group name="altcategoryMIS">Python Core zipfile</Group>
<Group name="altcategoryGDPR">Access Violation</Group>
</MetaInfo>
</Rule>
</RuleInfo>
</EngineData>
</FVDL>');
-- DDL and sample data population, end
SELECT p.value('@id', 'UNIQUEIDENTIFIER') AS ID
, c.value('@name', 'VARCHAR(30)')AS [Name]
, c.value('(./text())[1]', 'VARCHAR(30)')AS [Group]
FROM @tbl
CROSS APPLY xmldata.nodes('/FVDL/EngineData/RuleInfo/Rule') AS t1(p)
CROSS APPLY t1.p.nodes('MetaInfo/Group') AS t2(c);
Output
-------------------------------- ----------------- ---------------------
| ID | Name | Group |
-------------------------------- ----------------- ---------------------
| 13EFF385-69A9-494A-9C67-951FED | package | Python Core xml |
| 13EFF385-69A9-494A-9C67-951FED | inputsource | XML Document |
| 13EFF385-69A9-494A-9C67-951FED | audience | broad |
| E9DB1C0E-025E-4EBF-A804-6C3DA4 | altcategoryMIS | Python Core zipfile |
| E9DB1C0E-025E-4EBF-A804-6C3DA4 | altcategoryGDPR | Access Violation |
-------------------------------- ----------------- ---------------------
CodePudding user response:
OPENXML is a bit wonky and is outdated. If you need to use it, you need to provide the path down to <Group>
and then work your way back up to the other elements. This should do it for you based on your sample XML.
DECLARE @XML XML = N'<FVDL>
<EngineData>
<RuleInfo>
<Rule id="13EFF385-69A9-494A-9C67-951FEDAB25ED">
<MetaInfo>
<Group name="package">Python Core xml</Group>
<Group name="inputsource">XML Document</Group>
<Group name="audience">broad</Group>
</MetaInfo>
</Rule>
<Rule id="E9DB1C0E-025E-4EBF-A804-6C3DA413E652">
<MetaInfo>
<Group name="altcategoryMIS">Python Core zipfile</Group>
<Group name="altcategoryGDPR">Access Violation</Group>
</MetaInfo>
</Rule>
</RuleInfo>
</EngineData>
</FVDL>'
DECLARE @hDoc AS INT
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML
Select ID, name, [Group]
FROM OPENXML(@hDoc, 'FVDL/EngineData/RuleInfo/Rule/MetaInfo/Group')
WITH
(
id [varchar](100) '../../@id',
[name] [varchar](100) '@name',
[Group] [varchar](1000) '.'
)
EXEC sp_xml_removedocument @hDoc
CodePudding user response:
I strongly suggest you don't use OPENXML
, as it has many issues.
Instead use the newer XQuery functions, which are far simpler to use
- Note how one
.nodes
feeds into the next. This is only necessary because there are two separate levels of nodes that need breaking into separate rows.
SELECT
ID = rl.value('@id','uniqueidentifier'),
[name] = grp.value('@name', 'varchar(100)'),
[Group] = grp.value('text()[1]','varchar(1000)')
FROM XMLwithOpenXML
CROSS APPLY XMLData.nodes('FVDL/EngineData/RuleInfo/Rule') x1(rl)
CROSS APPLY x1.rl.nodes('MetaInfo/Group') x2(Grp);