2015-10-20 52 views
3

我有一個XML文件,我試圖解析它。該XML使用將具有相同標記的XML值分隔爲不同的行SQL Server

保存爲XML

通過Excel中創建因爲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值。

有沒有辦法做到這一點?

的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>領域

編輯

從我措辭的方式這個問題看起來好像是頭文件的名字已經被編入了,但是它們實際上被讀作<Cell><Data><Data/></Cell>中的行。我也不能肯定的部分成爲什麼樣的目的

這是<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> 
+0

我認爲「欄目.. .column ... column ...「部分命名列,在這種情況下,」名稱「,」用戶名「,」地址「和」電話「,是否​​正確?這些數據是否一致,還是必須靈活? (也就是說,你可以編寫這樣的代碼,使得這些列名在查詢中是硬編碼的嗎?還是可以有任意數量的列,有些缺失,還有一些新的等等)?它會影響你如何去做必須解決這個問題。 – pmbAustin

+0

@pmbAustin頭部名稱是硬編碼的,文件將始終採用此格式。至於你的第一個關於「列...」的問題,請參閱編輯。 –

回答

2

同一個用戶有兩個非常相似的問題。 OP決定刪除一個,並在此合併,並要求我將答案從那裏複製到此主題。

注意必須聲明爲「DEFAULT」的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) 
1

試試這樣說:我加了根元素暗示的命名空間,你必須把它拿出來(也是從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) 

編輯:你的路會像/Workbook[1]/Worksheet[1]/Table[1]/Row[1]

祝你好運!

+0

同一個用戶有一個非常類似的問題...需要來自兩個問題(尤其是全名稱空間)的信息。我在這裏給出了另一個答案:http://stackoverflow.com/a/33245508/5089204 – Shnugo

+0

你給那裏的答案工作。我將從這裏獲取額外的信息並將其放在另一個問題中,然後刪除這一個。 –

相關問題