使用SQL将XML文件解析为特定列
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用SQL将XML文件解析为特定列相关的知识,希望对你有一定的参考价值。
我有一个XML文件,如下所示:
<?xml version="1.0" encoding = "utf-8"?>
<CIM CIMVERSION="2.0" DTDVERSION="2.0">
<MESSAGE ID="1111" PROTOCOLVERSION="1.0">
<SIMPLEREQ>
<VALUE.NAMEDINSTANCE>
<INSTANCENAME CLASSNAME="DCIM_ControllerView">
<KEYBINDING NAME="InstanceID">
<KEYVALUE VALUETYPE="string">RAID.Integrated.1-1</KEYVALUE>
</KEYBINDING>
</INSTANCENAME>
<INSTANCE CLASSNAME="DCIM_ControllerView">
<PROPERTY NAME="LastUpdateTime" TYPE="string">
<VALUE>20170223172914.000000+000</VALUE>
<DisplayValue>2017-02-23T17:29:14</DisplayValue>
</PROPERTY>
<PROPERTY NAME="LastSystemInventoryTime" TYPE="string">
<VALUE>20170223172914.000000+000</VALUE>
<DisplayValue>2017-02-23T17:29:14</DisplayValue>
</PROPERTY>
<PROPERTY NAME="RealtimeCapability" TYPE="uint32">
<VALUE>6</VALUE>
<DisplayValue>Capable</DisplayValue>
</PROPERTY>
<PROPERTY NAME="SupportControllerBootMode" TYPE="uint8">
<VALUE>1</VALUE>
<DisplayValue>Supported</DisplayValue>
</PROPERTY>
<PROPERTY NAME="SupportEnhancedAutoForeignImport" TYPE="uint8">
<VALUE>1</VALUE>
<DisplayValue>Supported</DisplayValue>
</PROPERTY>
<PROPERTY NAME="MaxAvailablePCILinkSpeed" TYPE="string">
<VALUE>Generation 3</VALUE>
<DisplayValue>Generation 3</DisplayValue>
</PROPERTY>
<PROPERTY NAME="MaxPossiblePCILinkSpeed" TYPE="string">
<VALUE>Generation 3</VALUE>
<DisplayValue>Generation 3</DisplayValue>
</PROPERTY>
<PROPERTY NAME="PatrolReadState" TYPE="uint8">
<VALUE>1</VALUE>
<DisplayValue>Stopped</DisplayValue>
</PROPERTY>
<PROPERTY NAME="DriverVersion" TYPE="string">
<DisplayValue>Not Applicable</DisplayValue>
</PROPERTY>
<PROPERTY NAME="CacheSizeInMB" TYPE="uint32">
<VALUE>0</VALUE>
<DisplayValue>0 MB</DisplayValue>
</PROPERTY>
<PROPERTY NAME="SupportRAID10UnevenSpans" TYPE="uint8">
<VALUE>1</VALUE>
<DisplayValue>Supported</DisplayValue>
</PROPERTY>
<PROPERTY NAME="T10PICapability" TYPE="uint8">
<VALUE>1</VALUE>
<DisplayValue>Supported</DisplayValue>
</PROPERTY>
<PROPERTY NAME="SlicedVDCapability" TYPE="uint8">
<VALUE>1</VALUE>
<DisplayValue>Sliced Virtual Disk creation supported</DisplayValue>
</PROPERTY>
<PROPERTY NAME="CachecadeCapability" TYPE="uint8">
<VALUE>0</VALUE>
<DisplayValue>Cachecade Virtual Disk not supported</DisplayValue>
</PROPERTY>
<PROPERTY NAME="KeyID" TYPE="string">
<DisplayValue/>
</PROPERTY>
<PROPERTY NAME="EncryptionCapability" TYPE="uint8">
<VALUE>1</VALUE>
<DisplayValue>Local Key Management Capable</DisplayValue>
</PROPERTY>
<PROPERTY NAME="EncryptionMode" TYPE="uint8">
<VALUE>0</VALUE>
<DisplayValue>None</DisplayValue>
</PROPERTY>
<PROPERTY NAME="SecurityStatus" TYPE="uint32">
<VALUE>1</VALUE>
<DisplayValue>Encryption Capable</DisplayValue>
</PROPERTY>
<PROPERTY NAME="SASAddress" TYPE="string">
<VALUE>1111</VALUE>
<DisplayValue>1111</DisplayValue>
</PROPERTY>
<PROPERTY NAME="ProductName" TYPE="string">
<VALUE>PERC Mini</VALUE>
<DisplayValue>PERC Mini</DisplayValue>
</PROPERTY>
<PROPERTY NAME="DeviceCardSlotType" TYPE="string">
<VALUE>Unknown</VALUE>
<DisplayValue>Unknown</DisplayValue>
</PROPERTY>
<PROPERTY NAME="DeviceCardSlotLength" TYPE="uint8">
<VALUE>2</VALUE>
<DisplayValue>Unknown</DisplayValue>
</PROPERTY>
<PROPERTY NAME="DeviceCardDataBusWidth" TYPE="string">
<VALUE>Unknown</VALUE>
<DisplayValue>Unknown</DisplayValue>
</PROPERTY>
<PROPERTY NAME="DeviceCardManufacturer" TYPE="string">
<VALUE>DELL</VALUE>
<DisplayValue>DELL</DisplayValue>
</PROPERTY>
<PROPERTY NAME="PCISubDeviceID" TYPE="string">
<VALUE>1111</VALUE>
<DisplayValue>1F47</DisplayValue>
</PROPERTY>
<PROPERTY NAME="PCIDeviceID" TYPE="string">
<VALUE>1</VALUE>
<DisplayValue>1</DisplayValue>
</PROPERTY>
<PROPERTY NAME="PCISubVendorID" TYPE="string">
<VALUE>1</VALUE>
<DisplayValue>1</DisplayValue>
</PROPERTY>
<PROPERTY NAME="PCIVendorID" TYPE="string">
<VALUE>1</VALUE>
<DisplayValue>1</DisplayValue>
</PROPERTY>
<PROPERTY NAME="Function" TYPE="string">
<VALUE>0</VALUE>
<DisplayValue>0</DisplayValue>
</PROPERTY>
<PROPERTY NAME="Device" TYPE="string">
<VALUE>0</VALUE>
<DisplayValue>0</DisplayValue>
</PROPERTY>
<PROPERTY NAME="Bus" TYPE="string">
<VALUE>2</VALUE>
<DisplayValue>2</DisplayValue>
</PROPERTY>
<PROPERTY NAME="ControllerFirmwareVersion" TYPE="string">
<VALUE>00.00.00.00</VALUE>
<DisplayValue>00.00.00.00</DisplayValue>
</PROPERTY>
<PROPERTY NAME="PCISlot" TYPE="uint8">
<VALUE>0</VALUE>
<DisplayValue>0</DisplayValue>
</PROPERTY>
<PROPERTY NAME="RollupStatus" TYPE="uint32">
<VALUE>1</VALUE>
<DisplayValue>OK</DisplayValue>
</PROPERTY>
<PROPERTY NAME="PrimaryStatus" TYPE="uint32">
<VALUE>1</VALUE>
<DisplayValue>OK</DisplayValue>
</PROPERTY>
<PROPERTY NAME="DeviceDescription" TYPE="string">
<VALUE>Integrated RAID Controller 1</VALUE>
<DisplayValue>Integrated RAID Controller 1</DisplayValue>
</PROPERTY>
<PROPERTY NAME="FQDD" TYPE="string">
<VALUE>RAID.Integrated.1-1</VALUE>
<DisplayValue>RAID.Integrated.1-1</DisplayValue>
</PROPERTY>
<PROPERTY NAME="InstanceID" TYPE="string">
<VALUE>RAID.Integrated.1-1</VALUE>
<DisplayValue>RAID.Integrated.1-1</DisplayValue>
</PROPERTY>
</INSTANCE>
</VALUE.NAMEDINSTANCE>
</SIMPLEREQ>
</MESSAGE>
</CIM>
我能够将SQL引入并作为XML对象读取。目前,我使用SSIS将XML文本放在一个字符串中。
在SSIS中读取文件后,它将它带入我的数据库,进入如下的临时表:
现在可以将文件放入我的临时表中,我想使用触发器将它们解析为特定的列。请注意,XML字符串是UTF-8。此数据来自Dell硬件清单XML文件。 他们的文档在此图中概述了他们的XML模式:
我需要将XML数据转换为模仿该图的列格式。所以标题是:
CIM | Messgae | Classname | InstanceID | PropertyName |价值| DisplayValue
这些列将在XML中包含它们各自的数据
另外,正如我所提到的,它是utf-8格式。要在SQL中将其作为XML对象读取,我使用以下代码:
declare @XML xml
set @XML = (SELECT Top 1 REPLACE([XML], 'utf-8', 'utf-16')FROM [StagingTable])
SELECT @XML
此外,我有多个INSTANCENAME实例,其中有更多集INSTANCE,PROPERTY,VALUE,DISPLAYVALUE等。
以下是根据Dell文档的XML架构:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://schemas.dell.com/HWinventory/1/0/events"
elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:evt="http://schemas.dell.com/HWinventory/1/0/events">
<xs:element name="CIM">
<xs:complexType>
<xs:sequence>
<xs:element name="MESSAGE">
<xs:complexType>
<xs:sequence>
<xs:element name="SIMPLEREQ">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="VALUE.NAMEDINSTANCE">
<xs:complexType>
<xs:sequence>
<xs:element name="INSTANCENAME">
<xs:complexType>
<xs:sequence>
<xs:element name="KEYBINDING">
<xs:complexType>
<xs:sequence>
<xs:element name="KEYVALUE">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="VALUETYPE" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="NAME" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="CLASSNAME" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="INSTANCE">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="PROPERTY.ARRAY">
<xs:complexType>
<xs:sequence>
<xs:element name="VALUE.ARRAY">
<xs:complexType>
<xs:sequence>
<xs:element name="VALUE" type="xs:string" />
<xs:element name="DisplayValue" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="NAME" type="xs:string" use="required" />
<xs:attribute name="TYPE" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element maxOccurs="unbounded" name="PROPERTY">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="VALUE" type="xs:string" />
<xs:element name="DisplayValue" type="xs:string" />
</xs:sequence>
<xs:attribute name="NAME" type="xs:string" use="required" />
<xs:attribute name="TYPE" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="CLASSNAME" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="ID" type="xs:int" use="required" />
<xs:attribute name="PROTOCOLVERSION" type="xs:decimal" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
答案
以下查询将从您的XML中检索各种数据。它不完全是您所需要的,但它应该为您提供一个模板,用于您可能想要提取的任何值:
DECLARE @xml XML=
N'<CIM CIMVERSION="2.0" DTDVERSION="2.0">
<MESSAGE ID="4711" PROTOCOLVERSION="1.0">
<SIMPLEREQ>
<VALUE.NAMEDINSTANCE xmlns:fo="http://www.w3.org/1999/XSL/Format">
<INSTANCENAME CLASSNAME="DCIM_ControllerView">
<KEYBINDING NAME="InstanceID">
<KEYVALUE VALUETYPE="string">RAID.Slot.1-1</KEYVALUE>
</KEYBINDING>
</INSTANCENAME>
<INSTANCE CLASSNAME="DCIM_ControllerView">
<PROPERTY NAME="DriverVersion" TYPE="string">
<DisplayValue />
</PROPERTY>
<PROPERTY NAME="KeyID" TYPE="string">
<DisplayValue />
</PROPERTY>
<PROPERTY NAME="SASAddress" TYPE="string">
<VALUE>5782BCB00C577600</VALUE>
<DisplayValue>5782BCB00C577600</DisplayValue>
</PROPERTY>
<PROPERTY NAME="ProductName" TYPE="string">
<VALUE>PERC H310 Adapter</VALUE>
<DisplayValue>PERC H310 Adapter</DisplayValue>
</PROPERTY>
<PROPERTY NAME="DeviceCardSlotType" TYPE="string">
<VALUE>PCI Express x8</VALUE>
<DisplayValue>PCI Express x8</DisplayValue>
</PROPERTY>
<PROPERTY NAME="DeviceCardManufacturer" TYPE="string">
<VALUE>DELL</VALUE>
<DisplayValue>DELL</DisplayValue>
</PROPERTY>
<PROPERTY NAME="PCISubDeviceID" TYPE="string">
<VALUE>1F4E</VALUE>
<DisplayValue>1F4E</DisplayValue>
</PROPERTY>
<PROPERTY NAME="PCIDeviceID" TYPE="string">
<VALUE>73</VALUE>
<DisplayValue>73</DisplayValue>
</PROPERTY>
<PROPERTY NAME="PCISubVendorID" TYPE="string">
<VALUE>1028</VALUE>
<DisplayValue>1028</DisplayValue>
</PROPERTY>
<PROPERTY NAME="PCIVendorID" TYPE="string">
<VALUE>1000</VALUE>
<DisplayValue>1000</DisplayValue>
</PROPERTY>
<PROPERTY NAME="Function" TYPE="string">
<VALUE>0</VALUE>
<DisplayValue>0</DisplayValue>
</PROPERTY>
<PROPERTY NAME="Device" TYPE="string">
<VALUE>0</VALUE>
<DisplayValue>0</DisplayValue>
</PROPERTY>
<PROPERTY NAME="Bus" TYPE="string">
<VALUE>1</VALUE>
<DisplayValue>1</DisplayValue>
</PROPERTY>
<PROPERTY NAME="ControllerFirmwareVersion" TYPE="string">
<VALUE>20.10.1-0066</VALUE>
<DisplayValue>20.10.1-0066</DisplayValue>
</PROPERTY>
</INSTANCE>
</VALUE.NAMEDINSTANCE>
</SIMPLEREQ>
</MESSAGE>
</CIM>';
- 查询
SELECT @xml.value(N'(/CIM/@CIMVERSION)[1]',N'nvarchar(max)') AS CIM_version
,@xml.value(N'(/CIM/MESSAGE/@ID)[1]',N'nvarchar(max)') AS Message_Id
,@xml.value(N'(/CIM/MESSAGE/SIMPLEREQ/VALUE.NAMEDINSTANCE/INSTANCENAME/KEYBINDING/KEYVALUE/text())[1]',N'nvarchar(max)') AS Keybinding_Value
,prp.value(N'@NAME',N'nvarchar(max)') AS Prop_Name
,prp.value(N'(VALUE/text())[1]',N'nvarchar(max)') AS Prop_Value
,prp.value(N'(DisplayValue/text())[1]',N'nvarchar(max)') AS Prop_DisplayValue
FROM @xml.nodes(N'/CIM/MESSAGE/SIMPLEREQ/VALUE.NAMEDINSTANCE/INSTANCE/PROPERTY') AS A(prp);
结果
+-------------+------------+------------------+---------------------------+-------------------+-------------------+
| CIM_version | Message_Id | Keybinding_Value | Prop_Name | Prop_Value | Prop_DisplayValue |
+-------------+------------+------------------+---------------------------+-------------------+-------------------+
| 2.0 | 4711 | RAID.Slot.1-1 | DriverVersion | NULL | NULL |
+-------------+------------+------------------+---------------------------+-------------------+-------------------+
| 2.0 | 4711 | RAID.Slot.1-1 | KeyID | NULL | NULL |
+-------------+------------+------------------+---------------------------+-------------------+-------------------+
| 2.0 | 4711 | RAID.Slot.1-1 | SASAddress | 5782BCB00C577600 | 5782BCB00C577600 |
+-------------+------------+------------------+---------------------------+-------------------+-------------------+
| 2.0 | 4711 | RAID.Slot.1-1 | ProductName | PERC H310 Adapter | PERC H310 Adapter |
+-------------+------------+------------------+---------------------------+-------------------+-------------------+
| 2.0 | 4711 | RAID.Slot.1-1 | DeviceCardSlotType | PCI Express x8 | PCI Express x8 |
+-------------+------------+------------------+---------------------------+-------------------+-------------------+
| 2.0 | 4711 | RAID.Slot.1-1 | DeviceCardManufacturer | DELL | DELL |
+-------------+------------+------------------+---------------------------+-------------------+-------------------+
| 2.0 | 4711 | RAID.Slot.1-1 | PCISubDeviceID | 1F4E | 1F4E |
+-------------+------------+------------------+---------------------------+-------------------+-------------------+
| 2.0 | 4711 | RAID.Slot.1-1 | PCIDeviceID | 73 | 73 |
+-------------+------------+------------------+---------------------------+-------------------+-------------------+
| 2.0 | 4711 | RAID.Slot.1-1 | PCISubVendorID | 1028 | 1028 |
+-------------+------------+------------------+---------------------------+-------------------+-------------------+
| 2.0 | 4711 | RAID.Slot.1-1 | PCIVendorID | 1000 | 1000 |
+-------------+------------+------------------+---------------------------+-------------------+-------------------+
| 2.0 | 4711 | RAID.Slot.1-1 | Function | 0 | 0 |
+-------------+------------+------------------+---------------------------+-------------------+-------------------+
| 2.0 | 4711 | RAID.Slot.1-1 | Device | 0 | 0 |
+-------------+------------+------------------+---------------------------+-------------------+-------------------+
| 2.0 | 4711 | RAID.Slot.1-1 | Bus | 1 | 1 |
+-------------+------------+------------------+---------------------------+-------------------+-------------------+
| 2.0 | 4711 | RAID.Slot.1-1 | ControllerFirmwareVersion | 20.10.1-0066 | 20.10.1-0066 |
+-------------+------------+------------------+---------------------------+-------------------+-------------------+
以上是关于使用SQL将XML文件解析为特定列的主要内容,如果未能解决你的问题,请参考以下文章
在 NodeJs 中使用 fast-xml-parser 将特定标签解析为数组