【问题标题】:Problems querying查询问题
【发布时间】:2019-04-19 22:07:17
【问题描述】:

我正在尝试以我一贯的方式查询以下 XML,但由于它的声明和空的“NextQuantity”-“NextDate”字段,我在查询 XML 时遇到了麻烦。

这样做的正确方法是什么?

谢谢。

<StocksResp xmlns="http://xxxxxx" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Stocks>
    <Stock>
      <Sku>30101.06-L</Sku>
      <Quantity>247610</Quantity>
      <NextQuantity1>15243</NextQuantity1>
      <NextDate1>2019-02-27</NextDate1>
      <NextQuantity2 i:nil="true" />
      <NextDate2 />
      <NextQuantity3 i:nil="true" />
      <NextDate3 />
      <NextQuantity4 i:nil="true" />
      <NextDate4 />
      <NextQuantity5 i:nil="true" />
      <NextDate5 />
      <NextQuantity6 i:nil="true" />
      <NextDate6 />
    </Stock>
    <Stock>
      <Sku>30101.06-M</Sku>
      <Quantity>241606</Quantity>
      <NextQuantity1 i:nil="true" />
      <NextDate1 />
      <NextQuantity2 i:nil="true" />
      <NextDate2 />
      <NextQuantity3 i:nil="true" />
      <NextDate3 />
      <NextQuantity4 i:nil="true" />
      <NextDate4 />
      <NextQuantity5 i:nil="true" />
      <NextDate5 />
      <NextQuantity6 i:nil="true" />
      <NextDate6 />
    </Stock>
 </Stocks>
  <Count>4837</Count>
  <Currency i:nil="true" />
  <Language>ES</Language>
  <ErrorCode i:nil="true" />
  <ErrorMessage i:nil="true" />
</StocksResp>

================================================

DECLARE @xml XML
SELECT @xml = x.y FROM OPENROWSET (BULK 'file.xml',SINGLE_BLOB) as x(y)

SELECT  
   x.y.value('Sku[1]','varchar(15)'),
   x.y.value('Quantity[1]','int'),
   x.y.value('NextDate1[1]','varchar(20)'),
   x.y.value('NextQuantity1[1]','int'),
   'mr'
FROM   @xml.nodes('Stocks/Stock') x(y)

【问题讨论】:

  • 不清楚你在问什么 &lt;NextQuantity1&gt;15243&lt;/&gt; 不是有效的 XML。这只是Q中的一个错误吗?期望的结果是什么?你有什么问题?绝对看起来您应该使用 WITH XMLNAMESPACES 并在路径中包含 StocksResp
  • 马丁,对不起,这是一个错误的输入。我已经更正了。无论如何,也感谢您的帮助。

标签: sql-server xml tsql xml-namespaces


【解决方案1】:

这会有帮助吗?

DECLARE @xml XML=
N'<StocksResp xmlns="http://xxxxxx" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Stocks>
    <Stock>
      <Sku>30101.06-L</Sku>
      <Quantity>247610</Quantity>
      <NextQuantity1>15243</NextQuantity1>
      <NextDate1>2019-02-27</NextDate1>
      <NextQuantity2 i:nil="true" />
      <NextDate2 />
      <NextQuantity3 i:nil="true" />
      <NextDate3 />
      <NextQuantity4 i:nil="true" />
      <NextDate4 />
      <NextQuantity5 i:nil="true" />
      <NextDate5 />
      <NextQuantity6 i:nil="true" />
      <NextDate6 />
    </Stock>
    <Stock>
      <Sku>30101.06-M</Sku>
      <Quantity>241606</Quantity>
      <NextQuantity1 i:nil="true" />
      <NextDate1 />
      <NextQuantity2 i:nil="true" />
      <NextDate2 />
      <NextQuantity3 i:nil="true" />
      <NextDate3 />
      <NextQuantity4 i:nil="true" />
      <NextDate4 />
      <NextQuantity5 i:nil="true" />
      <NextDate5 />
      <NextQuantity6 i:nil="true" />
      <NextDate6 />
    </Stock>
 </Stocks>
  <Count>4837</Count>
  <Currency i:nil="true" />
  <Language>ES</Language>
  <ErrorCode i:nil="true" />
  <ErrorMessage i:nil="true" />
</StocksResp>';

-你需要声明默认命名空间。您不需要声明命名空间i...

WITH XMLNAMESPACES(DEFAULT 'http://xxxxxx','http://www.w3.org/2001/XMLSchema-instance' AS i)
SELECT 
       @xml.value(N'(/StocksResp/Count/text())[1]',N'int') AS StockResp_Count
      ,@xml.value(N'(/StocksResp/Currency/text())[1]',N'int') AS StockResp_Currency 
      ,st.value(N'(Sku/text())[1]',N'nvarchar(max)') AS Stock_Sku
      ,st.value(N'(Quantity/text())[1]',N'int') AS Stock_Quantity
      ,st.value(N'(NextQuantity1/text())[1]',N'int') AS Stock_NextQuantity1
      ,st.value(N'(NextDate1/text())[1]',N'date') AS Stock_NextDate1
      ,st.value(N'(NextQuantity2/text())[1]',N'int') AS Stock_NextQuantity2
      ,st.value(N'(NextDate2/text())[1]',N'date') AS Stock_NextDate2
      ,st.value(N'(NextQuantity3/text())[1]',N'int') AS Stock_NextQuantity3
      ,st.value(N'(NextDate3/text())[1]',N'date') AS Stock_NextDate3
      ,st.value(N'(NextQuantity4/text())[1]',N'int') AS Stock_NextQuantity4
      ,st.value(N'(NextDate4/text())[1]',N'date') AS Stock_NextDate4
      ,st.value(N'(NextQuantity5/text())[1]',N'int') AS Stock_NextQuantity5
      ,st.value(N'(NextDate5/text())[1]',N'date') AS Stock_NextDate5
      ,st.value(N'(NextQuantity6/text())[1]',N'int') AS Stock_NextQuantity6
      ,st.value(N'(NextDate6/text())[1]',N'date') AS Stock_NextDate6
FROM   @xml.nodes('/StocksResp/Stocks/Stock') A(st);

一些备注:

name-number 元素(Date1、Date2 等)是一个非常不好的习惯。如果你可以改变这一点,你应该使用一组嵌套的元素,并通过它们的位置或使用类似

的属性对它们进行编号
<Next index="1">
   <Date>2018-01-01</Date>
   <Quantity>1</Quantity>
</Next>
[... more of them ...]

你可以看到,我直接从变量中读取 just-once 值,而重复元素是从.nodes() 的派生表中获取的。

【讨论】:

  • 谢谢你,Shnugo。它工作正常。多亏了你,我今天学到了一些新东西。不幸的是,XML 不是我的,它来自我们的供应商之一,所以它不在我的手中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-26
  • 2021-10-04
  • 2011-08-24
  • 2011-02-04
相关资源
最近更新 更多