使用SQL Server将具有相同标记的XML值分隔为不同的行
我有一个XML文件,我正试图解析它。XML是使用Excel创建的 另存为XML 由于XML文件是从Microsoft Excel创建的,因此它具有以下标题:使用SQL Server将具有相同标记的XML值分隔为不同的行,sql,sql-server,xml,xquery,xquery-sql,Sql,Sql Server,Xml,Xquery,Xquery Sql,我有一个XML文件,我正试图解析它。XML是使用Excel创建的 另存为XML 由于XML文件是从Microsoft Excel创建的,因此它具有以下标题: <?xml version="1.0"?> <?mso-application progid="Excel.Sheet"?> <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsof
<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
并给出了这些结果:
Name Value
---- -----------
Data Jane Doe
Data JaneDoe
Data XYZ
Data (555)555-5555
我想做的是将其分为4行,因此我有如下内容:
Name UserName Address Phone
----- ---------- --------- ----------
Jane Doe JaneDoe XYZ (555)-555-5555
我试着选择一列作为
X.value('.[2]','varchar(max)') as UserName
但是我只得到了所有的NULL
值
有没有办法做到这一点
XML文件的一般结构如下所示:
<Workbook>
<DocumentProperties>
</DocumentProperties>
<ExcelWorkbook>
</ExcelWorkbook>
<Styles>
<Style>
</Style>
</Styles>
<Worksheet>
<Table>
<Column.../>
<Column.../>
<Column.../>
<Row>
<Cell.../>
<Cell><Data>...</Data></Cell>
<Cell><Data>...</Data></Cell>
<Cell><Data>...</Data></Cell>
<Cell><Data>...</Data></Cell>
<Cell.../>
</Row>
...
</Table>
</Worksheet>
...
...
...
...
...
我试图获取的信息在…
字段中
编辑
从我对问题的措辞来看,标题名称似乎已经在中编程,但实际上它们在
中被读取为行。我也不知道这个角色的作用是什么
这是
部分的开头:
<Table ss:ExpandedColumnCount="6" ss:ExpandedRowCount="2685" x:FullColumns="1"
x:FullRows="1">
<Column ss:AutoFitWidth="0" ss:Width="26.25"/>
<Column ss:AutoFitWidth="0" ss:Width="117" ss:Span="3"/>
<Column ss:Index="6" ss:AutoFitWidth="0" ss:Width="29.25"/>
<Row ss:AutoFitHeight="0" ss:Height="60"> --Contains the header names
<Cell ss:StyleID="s22"/>
<Cell ss:StyleID="s23"><Data ss:Type="String">Name</Data></Cell>
<Cell ss:StyleID="s23"><Data ss:Type="String">UserName</Data></Cell>
<Cell ss:StyleID="s23"><Data ss:Type="String">Address</Data></Cell>
<Cell ss:StyleID="s23"><Data ss:Type="String">Telephone Number</Data></Cell>
<Cell ss:StyleID="s22"/>
</Row>
<Row ss:AutoFitHeight="0" ss:Height="30"> --First record I would like to extract
<Cell ss:StyleID="s22"/>
<Cell ss:StyleID="s24"><Data ss:Type="String">John Smith</Data></Cell>
<Cell ss:StyleID="s24"><Data ss:Type="String">JSmith</Data></Cell>
<Cell ss:StyleID="s24"><Data ss:Type="String">ABC</Data></Cell>
<Cell ss:StyleID="s24"><Data ss:Type="String">(999) 999-9999</Data></Cell>
<Cell ss:StyleID="s22"/>
</Row>
--包含标题名称
名称
用户名
地址
电话号码
--我想提取的第一张唱片
约翰·史密斯
犹太教
基础知识
(999) 999-9999
试着这样做:我添加了一个根元素来暗示名称空间,您必须将其取出(也从XPath中取出),但您可以通过简单的复制、粘贴和执行在空查询窗口中测试这一点:
DECLARE @allUsers XML=
'<root xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
<Row ss:AutoFitHeight="0" ss:Height="30">
<Cell ss:StyleID="s22"/>
<Cell ss:StyleID="s24"><Data ss:Type="String">Jane Doe</Data></Cell>
<Cell ss:StyleID="s24"><Data ss:Type="String">JaneDoe</Data></Cell>
<Cell ss:StyleID="s24"><Data ss:Type="String">XYZ</Data></Cell>
<Cell ss:StyleID="s24"><Data ss:Type="String">(555) 555-5555</Data></Cell>
<Cell ss:StyleID="s22"/>
</Row>
</root>';
;WITH XMLNAMESPACES ('urn:schemas-microsoft-com:office:spreadsheet' as ss)
SELECT T.X.value('Cell[1]/Data[1]','varchar(max)') AS DontKnow1
,T.X.value('Cell[2]/Data[1]','varchar(max)') AS Name
,T.X.value('Cell[3]/Data[1]','varchar(max)') AS UserName
,T.X.value('Cell[4]/Data[1]','varchar(max)') AS DontKnow2
,T.X.value('Cell[5]/Data[1]','varchar(max)') AS Telephone
,T.X.value('Cell[6]/Data[1]','varchar(max)') AS DontKnow3
FROM @allUsers.nodes('/root/Row') as T(X)
DECLARE@allUsers XML=
'
无名氏
珍妮多
XYZ
(555) 555-5555
';
;使用XMLNAMESPACES('urn:schemas microsoft com:office:spreadsheet'作为ss)
选择T.X.value('Cell[1]/Data[1]','varchar(max')作为DontKnow1
,T.X.value('Cell[2]/Data[1]','varchar(max')作为名称
,T.X.value('Cell[3]/Data[1]','varchar(max')作为用户名
,T.X.value('Cell[4]/Data[1]','varchar(max)'),如所知2
,T.X.value('Cell[5]/Data[1]','varchar(max)')作为电话
,T.X.value('Cell[6]/Data[1]','varchar(max)'),如所知3
从@allUsers.nodes('/root/Row')作为T(X)
编辑:您的路径类似于/Workbook[1]/Worksheet[1]/Table[1]/Row[1]
祝你好运 同一用户提出了两个非常相似的问题。OP决定删除一个,并将其合并到这里,并要求我将我的答案从那里复制到这个线程 请注意必须声明为“默认”的xmlns命名空间: 简化了XML,但这个想法应该没问题
DECLARE @allUsers XML=
'<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet>
<Table>
<Row ss:AutoFitHeight="0" ss:Height="30">
<Cell ss:StyleID="s22"/>
<Cell ss:StyleID="s24"><Data ss:Type="String">Jane Doe</Data></Cell>
<Cell ss:StyleID="s24"><Data ss:Type="String">JaneDoe</Data></Cell>
<Cell ss:StyleID="s24"><Data ss:Type="String">XYZ</Data></Cell>
<Cell ss:StyleID="s24"><Data ss:Type="String">(555) 555-5555</Data></Cell>
<Cell ss:StyleID="s22"/>
</Row>
</Table>
</Worksheet>
</Workbook>';
;WITH XMLNAMESPACES ('urn:schemas-microsoft-com:office:spreadsheet' as ss
,DEFAULT 'urn:schemas-microsoft-com:office:spreadsheet')
SELECT T.X.value('Cell[1]/Data[1]','varchar(max)') AS DontKnow1
,T.X.value('Cell[2]/Data[1]','varchar(max)') AS Name
,T.X.value('Cell[3]/Data[1]','varchar(max)') AS UserName
,T.X.value('Cell[4]/Data[1]','varchar(max)') AS DontKnow2
,T.X.value('Cell[5]/Data[1]','varchar(max)') AS Telephone
,T.X.value('Cell[6]/Data[1]','varchar(max)') AS DontKnow3
FROM @allUsers.nodes('/Workbook/Worksheet/Table/Row') as T(X)
DECLARE@allUsers XML=
'
无名氏
珍妮多
XYZ
(555) 555-5555
';
;使用XMLNAMESPACES('urn:schemas-microsoft-com:office:spreadsheet'作为ss
,默认值为“urn:schemas microsoft com:office:spreadsheet”)
选择T.X.value('Cell[1]/Data[1]','varchar(max')作为DontKnow1
,T.X.value('Cell[2]/Data[1]','varchar(max')作为名称
,T.X.value('Cell[3]/Data[1]','varchar(max')作为用户名
,T.X.value('Cell[4]/Data[1]','varchar(max)'),如所知2
,T.X.value('Cell[5]/Data[1]','varchar(max)')作为电话
,T.X.value('Cell[6]/Data[1]','varchar(max)'),如所知3
从@allUsers.nodes('/Workbook/Worksheet/Table/Row')作为T(X)
我假设行上方的“column…column…column…”部分为列命名,在本例中为“Name”、“UserName”、“Address”和“Phone”,对吗?这些数据是一致的,还是必须灵活?(即,您是否可以编写代码,以便在查询中对这些列名进行硬编码?或者是否可以有任意数量的列、缺少的列、新的列等?)这会影响您处理问题的方式。@pmbAustin头名称是硬编码的,文件将始终采用这种格式。关于“column…”的第一个问题,请参见编辑。同一用户提出了一个非常类似的问题。。。这两个问题(特别是完整名称空间)都需要提供信息。我在这里给出了另一个答案:你在那里给出的答案是有效的。我将从这里获取额外的信息,并将其放在另一个问题中,然后删除此问题。
DECLARE @allUsers XML=
'<root xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
<Row ss:AutoFitHeight="0" ss:Height="30">
<Cell ss:StyleID="s22"/>
<Cell ss:StyleID="s24"><Data ss:Type="String">Jane Doe</Data></Cell>
<Cell ss:StyleID="s24"><Data ss:Type="String">JaneDoe</Data></Cell>
<Cell ss:StyleID="s24"><Data ss:Type="String">XYZ</Data></Cell>
<Cell ss:StyleID="s24"><Data ss:Type="String">(555) 555-5555</Data></Cell>
<Cell ss:StyleID="s22"/>
</Row>
</root>';
;WITH XMLNAMESPACES ('urn:schemas-microsoft-com:office:spreadsheet' as ss)
SELECT T.X.value('Cell[1]/Data[1]','varchar(max)') AS DontKnow1
,T.X.value('Cell[2]/Data[1]','varchar(max)') AS Name
,T.X.value('Cell[3]/Data[1]','varchar(max)') AS UserName
,T.X.value('Cell[4]/Data[1]','varchar(max)') AS DontKnow2
,T.X.value('Cell[5]/Data[1]','varchar(max)') AS Telephone
,T.X.value('Cell[6]/Data[1]','varchar(max)') AS DontKnow3
FROM @allUsers.nodes('/root/Row') as T(X)
DECLARE @allUsers XML=
'<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet>
<Table>
<Row ss:AutoFitHeight="0" ss:Height="30">
<Cell ss:StyleID="s22"/>
<Cell ss:StyleID="s24"><Data ss:Type="String">Jane Doe</Data></Cell>
<Cell ss:StyleID="s24"><Data ss:Type="String">JaneDoe</Data></Cell>
<Cell ss:StyleID="s24"><Data ss:Type="String">XYZ</Data></Cell>
<Cell ss:StyleID="s24"><Data ss:Type="String">(555) 555-5555</Data></Cell>
<Cell ss:StyleID="s22"/>
</Row>
</Table>
</Worksheet>
</Workbook>';
;WITH XMLNAMESPACES ('urn:schemas-microsoft-com:office:spreadsheet' as ss
,DEFAULT 'urn:schemas-microsoft-com:office:spreadsheet')
SELECT T.X.value('Cell[1]/Data[1]','varchar(max)') AS DontKnow1
,T.X.value('Cell[2]/Data[1]','varchar(max)') AS Name
,T.X.value('Cell[3]/Data[1]','varchar(max)') AS UserName
,T.X.value('Cell[4]/Data[1]','varchar(max)') AS DontKnow2
,T.X.value('Cell[5]/Data[1]','varchar(max)') AS Telephone
,T.X.value('Cell[6]/Data[1]','varchar(max)') AS DontKnow3
FROM @allUsers.nodes('/Workbook/Worksheet/Table/Row') as T(X)