在mssql中使用特定父节点查找XML

时间:2017-09-01 08:20:12

标签: sql-server xml

我有表,其中包含XML类型的列。此列中的某些值以

开头
<MyAuthenticationParams>
.....
</MyAuthenticationParams>

还有一些

<Sm1AuthenticationParams>
.......
</Sm1AuthenticationParams>

如何仅选择父节点 MyAuthenticationParams 的记录?谢谢你的帮助。

修改 这就是XML的样子

    <MyAuthenticationParams xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <AlsoParams> 
    <SecretKey>MVHXAQA5kF4Ab9siV4vPA4aVPn1EKhbqIBrpCZx2Hg</SecretKey>     <DynamicDescriptor />
  </AlsoParams>
  <myParams>
    <AccountName>Acc1</AccountName>
    <Username>testUsername</Username>
   </myParams>
</MyAuthenticationParams>

或者像这样

<Sm1AuthenticationParams xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <AccountName>XGwzJ6RR</AccountName>

  <SomeNumber>123456780</SomeNumber>
</Sm1AuthenticationParams>

2 个答案:

答案 0 :(得分:0)

SELECT
a.b.value('NODE_ONE[1]','nvarchar(max)') AS Node_One,
a.b.value('NODE_TWO[1]','nvarchar(max)') AS Node_Two
FROM @MyXML.nodes('XML_MAIN_NODE/MyAuthenticationParams') a(b)

由于您的XML在表中,请使用以下内容。

SELECT
a.b.value('NODE_ONE[1]','nvarchar(max)') AS Node_One,
a.b.value('NODE_TWO[1]','nvarchar(max)') AS Node_Two
FROM Plans s CROSS APPLY s.Params.nodes('XML_MAIN_NODE/MyAuthenticationParams') a(b)

在你的情况下,这是有效的。 PATH_TILL_MyAuthenticationParams是MyAuthenticationParams标记的父节点之前的路径。 的 So, if XML is like <root><nodeA><MyAuthenticationParams>...<MyAuthenticationParams><Other_tag></Other_tag></nodeA></root>, PATH_TILL_MyAuthenticationParams is 'root/nodeA'

DECLARE @xml XML
select @xml = a.b.query('*') FROM Plans s CROSS APPLY s.Params.nodes('PATH_TILL_MyAuthenticationParams') a(b)
PRINT CONVERT(NVARCHAR(MAX), @xml)

DECLARE @accName NVARCHAR(500)
DECLARE @userName NVARCHAR(500)
DECLARE @secretKey NVARCHAR(2000)
SELECT
@accName = a.b.value('AccountName[1]','nvarchar(max)'),
@userName = a.b.value('Username[1]','nvarchar(max)')
FROM @xml.nodes('MyAuthenticationParams/myParams') a(b)

PRINT @accName
PRINT @userName

SELECT
@secretKey = a.b.value('SecretKey[1]','nvarchar(max)')
FROM @xml.nodes('MyAuthenticationParams/AlsoParams') a(b)
PRINT @secretKey

修改 在单个查询中,

DECLARE @AccountName NVARCHAR(500) = ''
DECLARE @Username NVARCHAR(500) = ''
DECLARE @Key VARCHAR(500) = ''

    SELECT @AccountName = x.u.value('(/ROOT_NODE/.../MyAuthenticationParams/myParams/AccountName)[1]', 'nvarchar(max)')
        , @Username = x.u.value('(/ROOT_NODE/.../MyAuthenticationParams/myParams/Username)[1]', 'nvarchar(max)'),
        @Key = x.u.value('(/ROOT_NODE/.../MyAuthenticationParams/AlsoParams/SecretKey)[1]', 'nvarchar(max)')
    FROM Plans a  CROSS APPLY a.Params.nodes('ROOT_NODE') x(u)

    PRINT @AccountName
    PRINT @Username
    PRINT @Key

答案 1 :(得分:0)

你可以试试这个:

DECLARE @DataSource XML =
N'
<DataSource>
<parentA>
    <child1></child1>
    <child2></child2>
    <child3></child3>
</parentA>
<parentB>
    <child4></child4>
    <child5></child5>
    <child6></child6>
</parentB>
<parentA>
    <child7></child7>
    <child8></child8>
</parentA>
</DataSource>';


SELECT P.c.query('.')
      ,T.c.query('.')
FROM @DataSource.nodes('DataSource/parentA') P(c)
OUTER APPLY P.c.nodes('*') T(c);

enter image description here

我们的想法是使用nodes来获取所有parentA个节点(在您的情况下,这些节点是MyAuthenticationParams个节点)。然后,第二个nodes我们正在接收他们的孩子,但你可以从这里得到任何你想要的东西。