从SQL Server中的XML文件中读取主要详细信息数据

时间:2018-04-11 16:32:52

标签: xml tsql xpath xml-namespaces sql-server-2016

我有一个类似的XML文件:

<invoice xmlns:xsi="http://......" xmlns="http://..." xmlns:omismsg="http://..." omismsg:action="update">

    <status>1</status>
    <transNo>17AUAU0000118N</transNo>
    <transType>5</transType>
    <externalRefId/>
    <billExternalRef/>

    <invoiceDetails omismsg:action="update">
        <transNo>17AUAU0000118N</transNo>
        <transType>5</transType>
        <seqNo>001</seqNo>
    </invoiceDetails>

    <invoiceDetails omismsg:action="update">
        <transNo>17AUAU0000118N</transNo>
        <transType>5</transType>
        <seqNo>002</seqNo>
    </invoiceDetails>

</invoice>

我已经写了这个命令来提取所有数据

select
 c3.value('status[1]','int'),
 c3.value('transNo[1]','VARCHAR(255)'),
 c3.value('transType[1]','int'),
 c3.value('externalRefId[1]','VARCHAR(255)'),
 c3.value('billExternalRef[1]','VARCHAR(255)')

 ,c4.value('(transNo)[1]','VARCHAR(10)')
 ,c4.value('(transType)[1]','int')
 ,c4.value('(seqNo)[1]','VARCHAR(10)')
from
(
  select 
    cast(c1 as xml)
  from 
    OPENROWSET (BULK '\\SQL-CSLDataWarehousedevelopment\ETL-ToIMOS\test\invoice.xml', SINGLE_BLOB) as T1(c1)
)as T2(c2)
cross apply c2.nodes('/invoice') T3(c3)
cross apply c2.nodes('/invoice/invoiceDetails') T4(c4)

但结果是空的。

我检查了XML文件,发现如果我替换

<invoice xmlns:xsi="http://......" xmlns="http://..." xmlns:omismsg="http://..." omismsg:action="update">

<invoice>

<invoiceDetails omismsg:action="update">

<invoiceDetails>

它会起作用。 但实际上我可以更改xml文件。我该如何改变命令才能工作?

1 个答案:

答案 0 :(得分:1)

您遇到了命名空间问题。

有两种方法可供选择
  • 通配符名称空间
  • (推荐)声明并使用命名空间

试试这个

public string temp()
{
    string test = string.Empty;
    string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
    using (SqlConnection con = new SqlConnection(CS))
    {
        SqlCommand cmd = new SqlCommand("SELECT LEFT(CONVERT(VARCHAR(10),GETDATE(),120),4)
                            + CAST((DATEPART(ISOWK,GETDATE()) - 2) AS NVARCHAR(2))", con);
        con.Open();
        test = (string)cmd.ExecuteScalar();
        con.Close();
    }
    return test;
}


protected void gwPlanning_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.Cells.Count > 0)
    {
        //Translate header text
        if (e.Row.RowType == DataControlRowType.Header)
        {
            e.Row.Cells[12].Text = temp().ToString();    
        }
    }       
 }

- 此查询将使用DECLARE @xml XML= N'<invoice xmlns:xsi="http://......" xmlns="http://..." xmlns:omismsg="http://..." omismsg:action="update"> <status>1</status> <transNo>17AUAU0000118N</transNo> <transType>5</transType> <externalRefId /> <billExternalRef /> <invoiceDetails omismsg:action="update"> <transNo>17AUAU0000118N</transNo> <transType>5</transType> <seqNo>001</seqNo> </invoiceDetails> <invoiceDetails omismsg:action="update"> <transNo>17AUAU0000118N</transNo> <transType>5</transType> <seqNo>002</seqNo> </invoiceDetails> </invoice>'; 忽略命名空间

*:

- 此查询声明命名空间并相应地使用它们

select
 c3.value('(*:status/text())[1]','int'),
 c3.value('(*:transNo/text())[1]','VARCHAR(255)'),
 c3.value('(*:transType/text())[1]','int'),
 c3.value('(*:externalRefId/text())[1]','VARCHAR(255)'),
 c3.value('(*:billExternalRef/text())[1]','VARCHAR(255)'),
 c3.value('(@*:action)[1]','varchar(255)')

 ,c4.value('(*:transNo/text())[1]','VARCHAR(10)')
 ,c4.value('(*:transType/text())[1]','int')
 ,c4.value('(*:seqNo/text())[1]','VARCHAR(10)')
 ,c4.value('(@*:action)[1]','VARCHAR(10)')
from @xml.nodes('/*:invoice') T3(c3)
cross apply c3.nodes('*:invoiceDetails') T4(c4);

两者都返回相同的