简体   繁体   中英

SQL: Query XML node value, exclude nested node

I'm having trouble importing a new XML format into our MS SQL database. My document is looking similar to this.

<xml>
  <data>
    <email>test@mail.com</email>
    <isActive>
      true
      <previous>false</previous>
    </isActive>
  </data>
</xml>

My issue is that I cannot get the value 'true' for column "isActive" when attempting to query it it returns 'truefalse', the nested "previous" node is included. I cannot figure out how to exclude it or split it into 2 separate columns.

From what I understand this XML should be perfectly valid.

I've tried 2 approaches. The current SQL statement that the files were imported with before the format update using OPENXML, I've tried to specify also here to take just the first instance of isActive, but the first instance of course includes the "previous" node as it's contained within the "isActive" node.

select
  email,
  isActive
from
  openxml(@xmlDocument, '/data')
  with
  (
    email nvarchar(128) 'email',
    isActive nvarchar(12) 'isActive[1]'
    --isActive nvarchar(12) 'isActive'
  )

Using xquery

select
  data.col.value('(email)[1]', 'nvarchar(128)'),
  data.col.value('(isActive)[1]', 'nvarchar(12)')
from
  @xmlDocument.nodes('/data') as data(col)

While the example appears to be working, it is actually including both values behind the scenes (due to linebreak) If I attempt to convert it into boolean it shows the following.

Error Screenshot

    You can do this:
    DECLARE @xmlDocument XML =' <data>
        <email>test@mail.com</email>
        <isActive>
          true
          <previous>false</previous>
        </isActive>
      </data>'
    
    select
      data.col.value('(email)[1]', 'nvarchar(128)') AS [Email],
      data.col.value('(isActive)[1]', 'nvarchar(12)') AS [IsActive],
      data.col.value('(isActive/previous)[1]', 'nvarchar(12)') AS [IsActive_previous]
    from
      @xmlDocument.nodes('/data') as data(col)
[![enter image description here][1]][1]




select
  data.col.value('(email)[1]', 'nvarchar(128)') AS [Email],
  (CASE WHEN (data.col.value('(isActive)[1]', 'nvarchar(12)'))='false' THEN 0 ELSE 1 END) AS [IsActive],
  (CASE WHEN trim(data.col.value('(isActive/previous)[1]', 'nvarchar(12)'))='false' THEN 0 ELSE 1 END) AS [IsActive_previous]
from
  @xmlDocument.nodes('/data') as data(col)

1st Query Result在此处输入图像描述

2nd Query Result在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM