【问题标题】:How to retrieve attribute only using xQuery如何仅使用 xQuery 检索属性
【发布时间】:2014-04-05 12:10:53
【问题描述】:

我有一个类似于以下的函数,返回大块 xml(在生产环境中), 在应用程序的各个阶段,我们只需要从中检索部分元素或部分属性。

create function testrig.fxConfigurations(@context varchar(300)) returns xml as 
begin
return (select 
'<configurations realm="configuration">
    <context name="apera">
        <backends>
            <backend name="Hades">
                <os>HP Unix</os>
                <ip>nnn.nnn.nnn</ip>
                <db vender="Oracle" version="11g">
                    <netconnect>Data Source= (DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = hades)(PORT = 1521)(RECV_BUF_SIZE=1048576))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = baan)));Password=********;User ID=ItsMe;" providerName="Oracle.DataAccess.Client"
                    </netconnect>
                </db>
            </backend>
            <backend name="Athena">
                <os>HP Unix</os>
                <ip>nnn.nnn.nnn</ip>
                <db vender="Oracle" version="11g">
                    <netconnect>Data Source= (DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = hades)(PORT = 1521)(RECV_BUF_SIZE=1048576))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = baan)));Password=********;User ID=ItsMe;" providerName="Oracle.DataAccess.Client"
                    </netconnect>
                </db>
            </backend>
        </backends>
    </context>
</configurations>
')

end 
go

如何像这样使用 xQuery 仅检索属性名称,即“Hades”、“Athena”

select (testrig.fxConfigurations(null).query('configurations/context[@name="apera"]/backends').query('/descendant-or-self::*'))

【问题讨论】:

    标签: sql-server xml tsql xquery-sql


    【解决方案1】:

    如果您想连接 backend/@name 属性的所有值 (ala GROUP_CONCAT):

    select testrig.fxConfigurations(null)
       .query('data(configurations/context[@name="apera"]/backends/backend/@name)')
    

    如果您需要单独处理属性,您可能需要使用nodes 来提取它们:

    WITH cteXml AS
    (
        SELECT testrig.fxConfigurations(null)
               .query('configurations/context[@name="apera"]') as context
    )
    SELECT Nodes.node.value('@name', 'varchar(50)') AS backEndName
    FROM cteXml
        CROSS APPLY cteXml.context.nodes('//backends/backend') as Nodes(node);
    

    Fiddle here

    【讨论】:

    • 感谢 StuartLC,正是我们想要的。
    猜你喜欢
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-12
    • 1970-01-01
    相关资源
    最近更新 更多