使用 XML.Node 从 SSMS 中的 XML 读取属性

Read attribute from XML in SSMS using XML.Node

我正在尝试读取一个 XML 文件,目的是让 ddscontrol 达到 return

888

在一条记录中 和

999

在另一个。

同样,对于工具提示,我需要 return

TTT111

TTT222

尽管出于某种原因,我似乎无法超越 dds,但这是 SSMS 中 运行 的简化脚本:

DECLARE @XML AS XML = '
<Create xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">
    <ObjectDefinition>
        <Database>
            <ID>White Stuff BI OLAP Solution</ID>
            <Dimensions>
                <Dimension>
                    <ID>Dim Dynamic Date Filter</ID>
                    <Annotations>
                        <Annotation>
                            <Name>http://schemas.microsoft.com/DataWarehouse/Designer/1.0:DiagramLayout</Name>
                            <Value>
                                <dds xmlns="this is an XML namespace">123
                                    <ddscontrol tooltip="TTT111">888</ddscontrol></dds>
                            abc</Value>
                        </Annotation>
                        <Annotation>
                            <Name>http://schemas.microsoft.com/DataWarehouse/Designer/1.0:DiagramLayout</Name>
                            <Value>
                                <dds xmlns="this is an XML namespace">456
                                    <ddscontrol tooltip="TTT222">999</ddscontrol></dds>
                            abc</Value>
                        </Annotation>
                    </Annotations>
                </Dimension>
            </Dimensions>
        </Database>
    </ObjectDefinition>
</Create>'

;WITH XMLNAMESPACES 
(
    DEFAULT 'http://schemas.microsoft.com/analysisservices/2003/engine',
    'this is an XML namespace' AS ns2
                      
)


SELECT 
    a.value('(../../../../ID/text())[1]', 'nvarchar(100)') as [First ID]
    ,a.value('(../../ID/text())[1]', 'nvarchar(100)') as [Second ID]
    ,a.value('(Name/text())[1]', 'nvarchar(1000)') as [Name]
    ,a.value('(Value/text())[1]', 'nvarchar(1000)') as [Value]
    ,a.value('(Value/ns2:dds/text())[1]', 'nvarchar(1000)') as [dds]
    ,a.value('(Value/ns2:dds/ddscontrol/text())[1]', 'nvarchar(1000)') as [ddscontrol]
    ,a.value('(Value/ns2:dds/ddscontrol/@tooltip)[1]', 'nvarchar(1000)') as [tooltip]

FROM @XML.nodes('/Create/ObjectDefinition/Database/Dimensions/Dimension/Annotations/Annotation') as x1(a)

SSMS 中的结果:

正如@Larnu 已经提到的,XML 看起来不对。

请尝试以下解决方案。

要点:

  • 它使用了两个命名空间声明。
  • 最好不要向上遍历XML。
  • 出于性能原因,
  • ../text() 添加到 XPath 表达式。

SQL

DECLARE @xml AS XML = 
N'<Create xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">
    <ObjectDefinition>
        <Database>
            <ID>White Stuff BI OLAP Solution</ID>
            <Dimensions>
                <Dimension>
                    <ID>Dim Dynamic Date Filter</ID>
                    <Annotations>
                        <Annotation>
                            <Name>http://schemas.microsoft.com/DataWarehouse/Designer/1.0:DiagramLayout</Name>
                            <Value>
                                <dds xmlns="this is an XML namespace">123
                                    <ddscontrol tooltip="TTT111">888</ddscontrol>
                                </dds>abc</Value>
                        </Annotation>
                        <Annotation>
                            <Name>http://schemas.microsoft.com/DataWarehouse/Designer/1.0:DiagramLayout</Name>
                            <Value>
                                <dds xmlns="this is an XML namespace">456
                                    <ddscontrol tooltip="TTT222">999</ddscontrol>
                                </dds>abc</Value>
                        </Annotation>
                    </Annotations>
                </Dimension>
            </Dimensions>
        </Database>
    </ObjectDefinition>
</Create>';

;WITH XMLNAMESPACES 
(
    DEFAULT 'http://schemas.microsoft.com/analysisservices/2003/engine',
    'this is an XML namespace' AS ns2
)
SELECT a.value('(ID/text())[1]', 'nvarchar(100)') as [First ID]
    ,a.value('(Dimensions/Dimension/ID/text())[1]', 'nvarchar(100)') as [Second ID]
    ,b.value('(Name/text())[1]', 'nvarchar(1000)') as [Name]
    ,b.value('(Value/ns2:dds/text())[1]', 'nvarchar(1000)') as [dds]
    ,b.value('(Value/ns2:dds/ns2:ddscontrol/text())[1]', 'nvarchar(1000)') as ddscontrol
    ,b.value('(Value/ns2:dds/ns2:ddscontrol/@tooltip)[1]', 'nvarchar(1000)') as tooltip
FROM @xml.nodes('/Create/ObjectDefinition/Database') as t1(a)
    CROSS APPLY t1.a.nodes('Dimensions/Dimension/Annotations/Annotation') AS t2(b);