我有一个要解析的XML文件。XML是使用Excel通过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-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">
我尝试提取的数据按如下所示设置在块中:
<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>
现在,我的查询看起来像这样:
;WITH XMLNAMESPACES ('urn:schemas-microsoft-com:office:spreadsheet' as ss) select * from ( select X.value('local-name(.)[1]','varchar(max)') as Name, X.value('.[1]','varchar(max)') as Value from @allUsers.nodes('//*') as T(X) ) a where Name = 'Data'
并给我这些结果:
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价值。
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>
而我想要获取的信息在该<Data>...</Data>领域
<Data>...</Data>
编辑
从我对问题的措辞的方式来看,标题名称似乎已经被编程了,但是实际上它们被读为中的行<Cell><Data><Data/></Cell>。我也不确定该零件的作用是什么
<Cell><Data><Data/></Cell>
这是本<Row>节的开始:
<Row>
<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>
同一用户有两个非常相似的问题。OP决定删除一个并将其合并到此处,并要求我将答案从此处复制到该线程。
请注意必须声明为“ DEFAULT”的xmlns-namespace:
简化了您的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)