【问题标题】:Retrieve the value of an element using XPath in t-sql在 t-sql 中使用 XPath 检索元素的值
【发布时间】:2020-04-26 03:27:00
【问题描述】:

我在一个有六列的表中有一行。其中一列称为 MessageContent,它是一个包含 XML 文档的 nvarchar(max)。我想从表中检索所有六列:

SELECT col1
      ,col2
      ,col3
      ,MessageContent (element: ErrorMessage)
      ,col5
      ,col6
from tablea;

这甚至可能吗?我见过的例子都涉及返回XML,我只想要元素的值:ErrorMessage。

【问题讨论】:

  • 有可能。如果您可以提供最小的可重现样本,那就太好了:(1) DDL 和样本数据群,即 CREATE table() 加上 INSERT 语句。 (2) 你需要做什么,即逻辑。 (3) 基于样本数据的期望输出。 (4) 你的 SQL Server 版本 (SELECT @@version;)
  • SQL Server 有很好的 XML 支持。它甚至还有一个用于 xml 内容的数据类型,称为 - 你猜对了 - XML。将您的列转换为 xml 并按照此处的说明进行操作:stackoverflow.com/questions/899313/…

标签: sql-server xml tsql xpath


【解决方案1】:

这里有一个解决方案。有两点需要注意:(1)命名空间处理(2)TRY_CAST()处理DB表中'坏'的XML。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY(1,1) PRIMARY KEY, MessageContent NVARCHAR(MAX));
INSERT INTO @tbl
VALUES (N'<?xml version="1.0"?>
<Acknowledgement xmlns="http://localhost/MeetingBrokerServices">
    <DocumentId>60051951-8f28-47d3-8fd8-0ba89b537c87</DocumentId>
    <TransactionId>62820a70-97f5-42b0-922e-a5f0908b9c8f</TransactionId>
    <DocumentDate>2019-10-10T04:00:00.7475266Z</DocumentDate>
    <StatusCode>NPE</StatusCode>
    <Success>false</Success>
    <Errors>
        <Error>
            <Code>301</Code>
            <ErrorText>Invalid LocationIdentifier was received in the request. Valid LocationIdentifier must be populated and sent for this request to succeed. Request Details: ExternalRfpId: SecondaryExternalRfpId: RfpId: 12499772 SiteId: LocationIdentifierType: MeetingBroker LocationId: ExternalBookingId: 111.11 MbUserGuid: 625bb5f9-0bc7-4c7f-900a-a6436555ea19 RequestMetaDataGuid: BizTalk MessageId: c6e05156-4a35-4be4-b9fe-209173049539 Please see WebServiceTransactionLog and RequestMetaData for details.</ErrorText>
            <ErrorType>Critical</ErrorType>
        </Error>
    </Errors>
</Acknowledgement>');
-- DDL and sample data population, end

;WITH XMLNAMESPACES(DEFAULT 'http://localhost/MeetingBrokerServices'), rs AS 
(
    SELECT *
        , TRY_CAST(MessageContent AS XML) AS [config]
    FROM @tbl
)
SELECT ID
    , col.value('(ErrorText/text())[1]','VARCHAR(4000)') AS ErrorText
FROM rs AS tbl
    CROSS APPLY tbl.[config].nodes('/Acknowledgement/Errors/Error') AS tab(col);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-07
    • 2012-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    相关资源
    最近更新 更多