【问题标题】:Get values from xml nodes within sql statement从 sql 语句中的 xml 节点获取值
【发布时间】:2022-01-05 09:02:22
【问题描述】:

我在“输入”列中有 xml 格式的字符串数据,我需要从中获取特定的节点值。

举个例子:

我需要每个“错误 id”中的每个“error_text_1”值。

<error_protokoll>

<header>  
 <source>machine</source> 
</header>

<error_list>

 <error id='0'>
   <error_text_1>error0</error_text_1> 
 </error>

 <error id='1'>
   <error_text_1>error1</error_text_1>
 </error>

</error_list>

</error_protokoll>

以下 sql 语句仅返回 id=0 的“error_text_1”值。

SELECT top (10)

XML_INPUT.value('(error_protokoll/error_list/error/error_text_1)[1]', 'varchar(200)') error

FROM 
(
 convert(xml, SUBSTRING( REPLACE(INPUT, '{
 "xml" : "<?xml version=''1.0''?>', ''), 0 , len(REPLACE(INPUT, '{
 "xml" : "<?xml version=''1.0''?>', ''))-3)) as XML_INPUT

 FROM  [Storage].[ods].[table]

) a

我想要所有的,而不是只有第一项。

你能帮忙解决这个问题吗?

【问题讨论】:

  • 看起来您有包含 XML 的 JSON,也许您应该使用 OPENJSON 或 JSON_VALUE 来检索它。也不确定为什么要删除 &lt;?xml 序言,它应该在那里。请提供一个minimal reproducible example,其中包含您需要转换的实际值
  • @Charlieface,我编辑了原始帖子以显示输入列中的原始单元格值。由于“{}”括号和“”xml”:“”我将文本转换为xml。
  • 我已回滚该编辑,因为它使我现有的答案无效;社区对此表示严重不满。 Don't be a Chameleon.
  • 看起来CAST(JSON_VALUE(yourValue, '$.xml') AS xml) 应该可以解决问题

标签: sql sql-server xml database


【解决方案1】:

您需要在FROM 中使用nodes 以便每个error 元素获得1 行,然后您可以获得每个error_text_1 的值:

DECLARE @xml xml = '<error_protokoll>
    <header>
        <source>machine</source>
    </header>
    <error_list>
        <error id="0">
            <error_text_1>error0</error_text_1>
        </error>
        <error id="1">
            <error_text_1>error1</error_text_1>
        </error>
    </error_list>
</error_protokoll>';

SELECT X.e.value('(./error_text_1/text())[1]','varchar(200)') AS error_text_1
FROM @xml.nodes('error_protokoll/error_list/error')X(e);

如果 XML 在表格中,您的 FROM 将如下所示:

FROM dbo.YourTable YT
     CROSS APPLY YT.YourColumn.nodes('error_protokoll/error_list/error')YC(e);

【讨论】:

  • 问题是我需要先将字符串转换为 xml,所以我需要在原始语句中使用您的建议,执行如下操作:SELECT top (10) YC.e.value(' (./error_text_1/text())[1]','varchar(200)') error_tesxt_1 FROM (select cross apply convert(xml, SUBSTRING( REPLACE(INPUT, '{ "xml" : "', ''), 0 , len(REPLACE(INPUT, '{ "xml" : "', ''))-3))。节点('error_protokoll/error_list/error')YC(e) FROM [Storage].[ods].[table]) b
  • “问题是我需要先将字符串转换为 xml” 为什么你的 XML 不是 xml 首先,@Kristan?那是你的问题。如果要在 T-SQL 中解析 XML,则需要为xml。
  • 是的,你是绝对正确的,但不幸的是这里有一些违反 xml 结构的其他信息,因此首先我需要预处理并将其转换为 xml。 “XML_INPUT”终于有了正确的结构,但是我只能得到单个值,如原始代码@Larnu 所示。
  • 您问题中的 XML 是有效的 XML,@Kristan。如果您将 XML 存储为不是有效 XML 的 (n)varchar,并且您希望将其转换为有效的 XML,这是一个 不同 问题;您需要询问new question,并提供格式错误的 XML 示例。尽管 SQL Server 的字符串操作充其量是很差的。您需要修复数据,而且很可能需要在源头完成。
  • 请不要编辑问题以使现有答案无效,@Kristan。如果问题发生了变化,请联系new question。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-18
相关资源
最近更新 更多