简体   繁体   中英

T-SQL XML query filter node data

I've got quite large Xml data stored into binary field. And want to extract minimal information as it has relationships to other tables.

An example of truncated xml data:

<CIVersion xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/EM.FactoryEntities" z:Id="i1">
  <CSettings xmlns:d2p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs" z:Id="i2">
    <d2p1:Name>V_TM</d2p1:Name>
  </CSettings>
  <ComponentModel xmlns:d2p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs" z:Id="i4">
    <Id xmlns="http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities">0</Id>
    <d2p1:Components>
      <d2p1:CellComponent z:Id="i5">
        <d2p1:Children>
          <d2p1:CellComponent z:Id="i6">
            <d2p1:Children />
            <d2p1:Equipment xmlns:d7p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.CIs" z:Id="i7" i:type="d7p1:SConConfiguration">
              <d2p1:RequiredNode z:Id="i9">
                <Name>TM</Name>
                <Version>v1.0.0</Version>
              </d2p1:RequiredNode>
              <d2p1:Name>EqConnection</d2p1:Name>
            </d2p1:Equipment>
            <d2p1:EquipmentObjectType i:nil="true" />
            <d2p1:Name>JobFactory</d2p1:Name>
            <d2p1:Parameters />
          </d2p1:CellComponent>
          <d2p1:CellComponent z:Id="i14">
            <d2p1:Children />
            <d2p1:Equipment z:Ref="i7" />
            <d2p1:EquipmentObjectType>Loadport</d2p1:EquipmentObjectType>
            <d2p1:Name>P2</d2p1:Name>
            <d2p1:Parameters>
              <d2p1:ComponentParameter z:Id="i15">
              </d2p1:ComponentParameter>
            </d2p1:Parameters>
            <d2p1:Type>Interfaces.IPort</d2p1:Type>
          </d2p1:CellComponent>
          <d2p1:CellComponent z:Id="i36">
            <d2p1:Children />
            <d2p1:Equipment xmlns:d7p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.CIs" z:Id="i7" i:type="d7p1:SConConfiguration">
              <d2p1:RequiredNode z:Id="i8">
                <Name>TFF</Name>
                <Version>v1.0.2</Version>
              </d2p1:RequiredNode>
              <d2p1:Name>EqConnection2</d2p1:Name>
            </d2p1:Equipment>
            <d2p1:EquipmentObjectType i:nil="true" />
            <d2p1:Name>Synchronizer</d2p1:Name>
            <d2p1:Parameters />
          </d2p1:CellComponent>
        </d2p1:Children>
        <d2p1:Equipment z:Ref="i7" />
        <d2p1:EquipmentObjectType>Equipment</d2p1:EquipmentObjectType>
        <d2p1:Name>V_TM</d2p1:Name>
      </d2p1:CellComponent>
    </d2p1:Components>
  </ComponentModel>
    <Name>Virt_TM</Name>
</CIVersion>

I need to extract only multiple values for 'd2p1:RequiredNode' node. So above example returns:

<RequiredNodes>
  <d2p1:RequiredNode z:Id="i9">
    <Name>TM</Name>
    <Version>v1.0.0</Version>
  </d2p1:RequiredNode>
  <:RequiredNode z:Id="i9">
    <Name>TFF</Name>
    <Version>v1.0.2</Version>
  </d2p1:RequiredNode>
</RequiredNodes>

This line returns the CSettings value:

;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/EM.FactoryEntities', 
        'http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs' as "d2p1")

SELECT TOP 1000 [ID],
    Convert(Xml,[CONFIGURATION]).query('/CIVersion/CSettings') AS CSettings
  FROM [TABLE_NAME]

I need same query correctly working for Oracle and MsSQL.

In SQL Server you can do this:

;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/EM.FactoryEntities', 
        'http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs' as "d2p1")

SELECT CAST('<RequiredNode>'+CAST(nd.query('.') as varchar(8000)) +'</RequiredNode>'AS xml)
FROM [TABLE_NAME]
CROSS APPLY [TABLE_NAME].[CONFIGURATION].nodes('//d2p1:RequiredNode') results(nd);

This query does not strip the name spaces from name and version but that should not be too hard. Here's the code that I used for testing this. Note that I added the missing namespaces to your XML.

IF object_id('tempdb..#x') IS NOT NULL DROP TABLE #x;
CREATE TABLE #x (id int identity, xmldata xml);

INSERT #x (xmldata) VALUES 
('<CIVersion xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/EM.FactoryEntities" z:Id="i1">
  <CSettings xmlns:d2p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs" z:Id="i2">
    <d2p1:Name>V_TM</d2p1:Name>
  </CSettings>
  <ComponentModel xmlns:d2p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs" z:Id="i4">
    <Id xmlns="http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities">0</Id>
    <d2p1:Components>
      <d2p1:CellComponent z:Id="i5">
        <d2p1:Children>
          <d2p1:CellComponent z:Id="i6">
            <d2p1:Children />
            <d2p1:Equipment xmlns:d7p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.CIs" z:Id="i7" i:type="d7p1:SConConfiguration">
              <d2p1:RequiredNode z:Id="i9">
                <Name>TM</Name>
                <Version>v1.0.0</Version>
              </d2p1:RequiredNode>
              <d2p1:Name>EqConnection</d2p1:Name>
            </d2p1:Equipment>
            <d2p1:EquipmentObjectType i:nil="true" />
            <d2p1:Name>JobFactory</d2p1:Name>
            <d2p1:Parameters />
          </d2p1:CellComponent>
          <d2p1:CellComponent z:Id="i14">
            <d2p1:Children />
            <d2p1:Equipment z:Ref="i7" />
            <d2p1:EquipmentObjectType>Loadport</d2p1:EquipmentObjectType>
            <d2p1:Name>P2</d2p1:Name>
            <d2p1:Parameters>
              <d2p1:ComponentParameter z:Id="i15">
              </d2p1:ComponentParameter>
            </d2p1:Parameters>
            <d2p1:Type>Interfaces.IPort</d2p1:Type>
          </d2p1:CellComponent>
          <d2p1:CellComponent z:Id="i36">
            <d2p1:Children />
            <d2p1:Equipment xmlns:d7p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.CIs" z:Id="i7" i:type="d7p1:SConConfiguration">
              <d2p1:RequiredNode z:Id="i9">
                <Name>TFF</Name>
                <Version>v1.0.2</Version>
              </d2p1:RequiredNode>
              <d2p1:Name>EqConnection2</d2p1:Name>
            </d2p1:Equipment>
            <d2p1:EquipmentObjectType i:nil="true" />
            <d2p1:Name>Synchronizer</d2p1:Name>
            <d2p1:Parameters />
          </d2p1:CellComponent>
        </d2p1:Children>
        <d2p1:Equipment z:Ref="i7" />
        <d2p1:EquipmentObjectType>Equipment</d2p1:EquipmentObjectType>
        <d2p1:Name>V_TM</d2p1:Name>
      </d2p1:CellComponent>
    </d2p1:Components>
  </ComponentModel>
    <Name>Virt_TM</Name>
</CIVersion>');

;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/EM.FactoryEntities', 
        'http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs' as "d2p1")

SELECT 
  RequiredNode = CAST('<RequiredNode>'+CAST(nd.query('.') as varchar(8000)) +'</RequiredNode>'AS xml),
  [Name]       = nd.value('(*:Name)[1]', 'varchar(8000)'),
  [Version]    = nd.value('(*:Version)[1]', 'varchar(8000)')
FROM #x
CROSS APPLY xmldata.nodes('//d2p1:RequiredNode') results(nd);

Results:

<RequiredNode>
  <d2p1:RequiredNode xmlns:d2p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs" xmlns:p1="http://schemas.microsoft.com/2003/10/Serialization/" p1:Id="i9">
    <p2:Name xmlns:p2="http://schemas.datacontract.org/2004/07/EM.FactoryEntities">TM</p2:Name>
    <p3:Version xmlns:p3="http://schemas.datacontract.org/2004/07/EM.FactoryEntities">v1.0.0</p3:Version>
  </d2p1:RequiredNode>
</RequiredNode>
<RequiredNode>
  <d2p1:RequiredNode xmlns:d2p1="http://schemas.datacontract.org/2004/07/EM.ConfigData.FactoryEntities.CIs" xmlns:p1="http://schemas.microsoft.com/2003/10/Serialization/" p1:Id="i9">
    <p2:Name xmlns:p2="http://schemas.datacontract.org/2004/07/EM.FactoryEntities">TFF</p2:Name>
    <p3:Version xmlns:p3="http://schemas.datacontract.org/2004/07/EM.FactoryEntities">v1.0.2</p3:Version>
  </d2p1:RequiredNode>
</RequiredNode>

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