Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用SQL Server将具有相同标记的XML值分隔为不同的行_Sql_Sql Server_Xml_Xquery_Xquery Sql - Fatal编程技术网

使用SQL Server将具有相同标记的XML值分隔为不同的行

使用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文件,我正试图解析它。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-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)