如何从数据库字段中解析 XML?
How can I parse XML from database field?
与以下 XML.
合作
<TEMPLATE>
<TEMPLATE_FIELD prompt="TEST_ONE" data_type="8" tag="TEST_ONE" required="0" is_radio="0" default_value="" SQL="SELECT * FROM DBO.SOME_NEW_TEST" />
<TEMPLATE_FIELD prompt="TEST_TWO" data_type="8" tag="TEST_TWO" required="0" is_radio="0" default_value="" SQL="SELECT * FROM DBO.SOME_NEW_TEST" />
<TEMPLATE_FIELD prompt="TEST_THREE" data_type="8" tag="TEST_THREE" required="0" is_radio="0" default_value="" SQL="SELECT * FROM DBO.SOME_NEW_TEST" />
我正在尝试获取以下内容 - 或类似的内容,以便我可以有效地阅读这些字段。
我试过其他几个问题,发现这个问题的第三个答案很有希望 -- 因为我希望能够在 SQL 中解析而不是使用外部语言或者创建一个文件。如果创建文件更容易,请随时分享。我已经尝试了下面代码的几种变体,但得到的不是“空白”就是 NULL。
declare @xml as xml
set @xml = (SELECT xml_field from fooXMLtable)
select @xml
;with cte as (
select @xml xmlstring
)
SELECT
xmlstring.value('(/TEMPLATE//TEMPLATE_FIELD/prompt/node())[3]','VARCHAR(max)')
as prompt
首先nodes()
to get the TEMPLATE_FIELD
elements a a table and then select from that table using value()
从属性中获取值。
SELECT tf.value('@prompt', 'varchar(MAX)') prompt,
tf.value('@data_type', 'integer') data_type,
...
FROM @xml.nodes('/TEMPLATE/TEMPLATE_FIELD') tf
(tf);
请尝试以下解决方案。
这是一个最小的可重现示例。您可以将它原样复制到 SSMS,运行 它,并探索它的作用。
它正在使用 XQuery 及其方法:.nodes()
和 .value()
。
无需使用临时 T-SQL 变量 @xml
作为 XML 数据占位符。
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmldata XML);
INSERT INTO @tbl (xmldata) VALUES
(N'<TEMPLATE>
<TEMPLATE_FIELD prompt="TEST_ONE" data_type="8" tag="TEST_ONE" required="0"
is_radio="0" default_value=""
SQL="SELECT * FROM DBO.SOME_NEW_TEST"/>
<TEMPLATE_FIELD prompt="TEST_TWO" data_type="8" tag="TEST_TWO" required="0"
is_radio="0" default_value=""
SQL="SELECT * FROM DBO.SOME_NEW_TEST"/>
<TEMPLATE_FIELD prompt="TEST_THREE" data_type="8" tag="TEST_THREE"
required="0" is_radio="0" default_value=""
SQL="SELECT * FROM DBO.SOME_NEW_TEST"/>
</TEMPLATE>');
-- DDL and sample data population, end
SELECT ID
, c.value('@prompt', 'VARCHAR(30)') AS prompt
, c.value('@data_type', 'INT') AS data_type
, c.value('@tag', 'VARCHAR(30)') AS tag
, c.value('@required', 'INT') AS [required]
, c.value('@is_radio', 'INT') AS [is_radio]
, c.value('@default_value', 'VARCHAR(30)') AS default_value
, c.value('@SQL', 'VARCHAR(MAX)') AS [SQL]
FROM @tbl CROSS APPLY xmldata.nodes('/TEMPLATE/TEMPLATE_FIELD') AS t(c);
输出
+----+------------+-----------+------------+----------+----------+---------------+---------------------------------+
| ID | prompt | data_type | tag | required | is_radio | default_value | SQL |
+----+------------+-----------+------------+----------+----------+---------------+---------------------------------+
| 1 | TEST_ONE | 8 | TEST_ONE | 0 | 0 | | SELECT * FROM DBO.SOME_NEW_TEST |
| 1 | TEST_TWO | 8 | TEST_TWO | 0 | 0 | | SELECT * FROM DBO.SOME_NEW_TEST |
| 1 | TEST_THREE | 8 | TEST_THREE | 0 | 0 | | SELECT * FROM DBO.SOME_NEW_TEST |
+----+------------+-----------+------------+----------+----------+---------------+---------------------------------+
如果您使用的是 MSSQL,这应该可行:
DECLARE @xml XML = '<TEMPLATE>
<TEMPLATE_FIELD prompt="TEST_ONE" data_type="8" tag="TEST_ONE" required="0" is_radio="0" default_value="" SQL="SELECT * FROM DBO.SOME_NEW_TEST" />
<TEMPLATE_FIELD prompt="TEST_TWO" data_type="8" tag="TEST_TWO" required="0" is_radio="0" default_value="" SQL="SELECT * FROM DBO.SOME_NEW_TEST" />
<TEMPLATE_FIELD prompt="TEST_THREE" data_type="8" tag="TEST_THREE" required="0" is_radio="0" default_value="" SQL="SELECT * FROM DBO.SOME_NEW_TEST" />
</TEMPLATE>'
SELECT
T.C.value('./@prompt', 'nvarchar(50)') as Prompt,
T.C.value('./@data_type', 'int') as DataType,
T.C.value('./@tag', 'nvarchar(50)') as Tag,
T.C.value('./@required', 'bit') as Required,
T.C.value('./@is_radio', 'bit') as IsRadio,
T.C.value('./@default_value', 'nvarchar(max)') as DefaultValue,
T.C.value('./@SQL', 'nvarchar(max)') as Query
FROM @xml.nodes('/TEMPLATE/TEMPLATE_FIELD') T(C)
与以下 XML.
合作<TEMPLATE>
<TEMPLATE_FIELD prompt="TEST_ONE" data_type="8" tag="TEST_ONE" required="0" is_radio="0" default_value="" SQL="SELECT * FROM DBO.SOME_NEW_TEST" />
<TEMPLATE_FIELD prompt="TEST_TWO" data_type="8" tag="TEST_TWO" required="0" is_radio="0" default_value="" SQL="SELECT * FROM DBO.SOME_NEW_TEST" />
<TEMPLATE_FIELD prompt="TEST_THREE" data_type="8" tag="TEST_THREE" required="0" is_radio="0" default_value="" SQL="SELECT * FROM DBO.SOME_NEW_TEST" />
我正在尝试获取以下内容 - 或类似的内容,以便我可以有效地阅读这些字段。
我试过其他几个问题,发现这个问题的第三个答案很有希望 -- 因为我希望能够在 SQL 中解析而不是使用外部语言或者创建一个文件。如果创建文件更容易,请随时分享。我已经尝试了下面代码的几种变体,但得到的不是“空白”就是 NULL。
declare @xml as xml
set @xml = (SELECT xml_field from fooXMLtable)
select @xml
;with cte as (
select @xml xmlstring
)
SELECT
xmlstring.value('(/TEMPLATE//TEMPLATE_FIELD/prompt/node())[3]','VARCHAR(max)')
as prompt
首先nodes()
to get the TEMPLATE_FIELD
elements a a table and then select from that table using value()
从属性中获取值。
SELECT tf.value('@prompt', 'varchar(MAX)') prompt,
tf.value('@data_type', 'integer') data_type,
...
FROM @xml.nodes('/TEMPLATE/TEMPLATE_FIELD') tf
(tf);
请尝试以下解决方案。
这是一个最小的可重现示例。您可以将它原样复制到 SSMS,运行 它,并探索它的作用。
它正在使用 XQuery 及其方法:.nodes()
和 .value()
。
无需使用临时 T-SQL 变量 @xml
作为 XML 数据占位符。
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmldata XML);
INSERT INTO @tbl (xmldata) VALUES
(N'<TEMPLATE>
<TEMPLATE_FIELD prompt="TEST_ONE" data_type="8" tag="TEST_ONE" required="0"
is_radio="0" default_value=""
SQL="SELECT * FROM DBO.SOME_NEW_TEST"/>
<TEMPLATE_FIELD prompt="TEST_TWO" data_type="8" tag="TEST_TWO" required="0"
is_radio="0" default_value=""
SQL="SELECT * FROM DBO.SOME_NEW_TEST"/>
<TEMPLATE_FIELD prompt="TEST_THREE" data_type="8" tag="TEST_THREE"
required="0" is_radio="0" default_value=""
SQL="SELECT * FROM DBO.SOME_NEW_TEST"/>
</TEMPLATE>');
-- DDL and sample data population, end
SELECT ID
, c.value('@prompt', 'VARCHAR(30)') AS prompt
, c.value('@data_type', 'INT') AS data_type
, c.value('@tag', 'VARCHAR(30)') AS tag
, c.value('@required', 'INT') AS [required]
, c.value('@is_radio', 'INT') AS [is_radio]
, c.value('@default_value', 'VARCHAR(30)') AS default_value
, c.value('@SQL', 'VARCHAR(MAX)') AS [SQL]
FROM @tbl CROSS APPLY xmldata.nodes('/TEMPLATE/TEMPLATE_FIELD') AS t(c);
输出
+----+------------+-----------+------------+----------+----------+---------------+---------------------------------+
| ID | prompt | data_type | tag | required | is_radio | default_value | SQL |
+----+------------+-----------+------------+----------+----------+---------------+---------------------------------+
| 1 | TEST_ONE | 8 | TEST_ONE | 0 | 0 | | SELECT * FROM DBO.SOME_NEW_TEST |
| 1 | TEST_TWO | 8 | TEST_TWO | 0 | 0 | | SELECT * FROM DBO.SOME_NEW_TEST |
| 1 | TEST_THREE | 8 | TEST_THREE | 0 | 0 | | SELECT * FROM DBO.SOME_NEW_TEST |
+----+------------+-----------+------------+----------+----------+---------------+---------------------------------+
如果您使用的是 MSSQL,这应该可行:
DECLARE @xml XML = '<TEMPLATE>
<TEMPLATE_FIELD prompt="TEST_ONE" data_type="8" tag="TEST_ONE" required="0" is_radio="0" default_value="" SQL="SELECT * FROM DBO.SOME_NEW_TEST" />
<TEMPLATE_FIELD prompt="TEST_TWO" data_type="8" tag="TEST_TWO" required="0" is_radio="0" default_value="" SQL="SELECT * FROM DBO.SOME_NEW_TEST" />
<TEMPLATE_FIELD prompt="TEST_THREE" data_type="8" tag="TEST_THREE" required="0" is_radio="0" default_value="" SQL="SELECT * FROM DBO.SOME_NEW_TEST" />
</TEMPLATE>'
SELECT
T.C.value('./@prompt', 'nvarchar(50)') as Prompt,
T.C.value('./@data_type', 'int') as DataType,
T.C.value('./@tag', 'nvarchar(50)') as Tag,
T.C.value('./@required', 'bit') as Required,
T.C.value('./@is_radio', 'bit') as IsRadio,
T.C.value('./@default_value', 'nvarchar(max)') as DefaultValue,
T.C.value('./@SQL', 'nvarchar(max)') as Query
FROM @xml.nodes('/TEMPLATE/TEMPLATE_FIELD') T(C)