[英]Unable to parse XML with namespace
嘗試從treasury.gov解析XML,它使用兩個名稱空間。 但是,我似乎無法從XML中提取數據。 我的查詢沒有任何回報。 我嘗試將名稱空間添加到prepareoc,但是沒有返回任何數據。 命名空間是問題,就像我刪除它們一樣,我的代碼也可以工作。 解決方法是,使用replace消除名稱空間以“清理” XML。 這樣就完全消除了名稱空間,呈現出直接的XML。 盡管此方法有效,但卻非常丑陋,而且顯然不是解決問題的正確方法。
DECLARE @xml AS XML;
DECLARE @idoc INT;
SET @xml = '
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xml:base="http://data.treasury.gov/Feed.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
<title type="text">DailyTreasuryYieldCurveRateData</title>
<id>http://data.treasury.gov/feed.svc/DailyTreasuryYieldCurveRateData</id>
<updated>2019-05-30T20:27:58Z</updated>
<link rel="self" title="DailyTreasuryYieldCurveRateData" href="DailyTreasuryYieldCurveRateData" />
<entry>
<id>http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(1)</id>
<title type="text"></title>
<updated>2019-05-30T20:27:58Z</updated>
<author>
<name />
</author>
<link rel="edit" title="DailyTreasuryYieldCurveRateDatum" href="DailyTreasuryYieldCurveRateData(1)" />
<category term="TreasuryDataWarehouseModel.DailyTreasuryYieldCurveRateDatum" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<content type="application/xml">
<m:properties>
<d:Id m:type="Edm.Int32">1</d:Id>
<d:NEW_DATE m:type="Edm.DateTime">1997-01-02T00:00:00</d:NEW_DATE>
<d:BC_1MONTH m:type="Edm.Double" m:null="true" />
<d:BC_2MONTH m:type="Edm.Double" m:null="true" />
<d:BC_3MONTH m:type="Edm.Double">5.190000057220459</d:BC_3MONTH>
<d:BC_6MONTH m:type="Edm.Double">5.3499999046325684</d:BC_6MONTH>
<d:BC_1YEAR m:type="Edm.Double">5.630000114440918</d:BC_1YEAR>
<d:BC_2YEAR m:type="Edm.Double">5.96999979019165</d:BC_2YEAR>
<d:BC_3YEAR m:type="Edm.Double">6.130000114440918</d:BC_3YEAR>
<d:BC_5YEAR m:type="Edm.Double">6.3000001907348633</d:BC_5YEAR>
<d:BC_7YEAR m:type="Edm.Double">6.4499998092651367</d:BC_7YEAR>
<d:BC_10YEAR m:type="Edm.Double">6.5399999618530273</d:BC_10YEAR>
<d:BC_20YEAR m:type="Edm.Double">6.8499999046325684</d:BC_20YEAR>
<d:BC_30YEAR m:type="Edm.Double">6.75</d:BC_30YEAR>
<d:BC_30YEARDISPLAY m:type="Edm.Double">0</d:BC_30YEARDISPLAY>
</m:properties>
</content>
</entry>
</feed>
'
EXEC sp_XML_PrepareDocument @iDoc OUTPUT, @xml, '<feed xml:base="http://data.treasury.gov/Feed.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:x="http://www.w3.org/2005/Atom">';
SELECT *
FROM OPENXML(@iDoc, 'feed/entry/content/m:properties/' )
WITH
(
[Id] VARCHAR(100) 'd:Id'
,[Date] VARCHAR(100) 'd:NEW_DATE'
)
EXEC sp_xml_removedocument @iDoc
Id和Date列不返回任何數據。 如果取消命名空間,它將按預期返回數據。
與FROM OPENXML
一起使用的方法以及用於准備和刪除文檔的存儲過程已經過時了,不應再使用。 而是使用本機XML方法:
您的XML
DECLARE @xml XML =
'<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xml:base="http://data.treasury.gov/Feed.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
<title type="text">DailyTreasuryYieldCurveRateData</title>
<id>http://data.treasury.gov/feed.svc/DailyTreasuryYieldCurveRateData</id>
<updated>2019-05-30T20:27:58Z</updated>
<link rel="self" title="DailyTreasuryYieldCurveRateData" href="DailyTreasuryYieldCurveRateData" />
<entry>
<id>http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(1)</id>
<title type="text"></title>
<updated>2019-05-30T20:27:58Z</updated>
<author>
<name />
</author>
<link rel="edit" title="DailyTreasuryYieldCurveRateDatum" href="DailyTreasuryYieldCurveRateData(1)" />
<category term="TreasuryDataWarehouseModel.DailyTreasuryYieldCurveRateDatum" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<content type="application/xml">
<m:properties>
<d:Id m:type="Edm.Int32">1</d:Id>
<d:NEW_DATE m:type="Edm.DateTime">1997-01-02T00:00:00</d:NEW_DATE>
<d:BC_1MONTH m:type="Edm.Double" m:null="true" />
<d:BC_2MONTH m:type="Edm.Double" m:null="true" />
<d:BC_3MONTH m:type="Edm.Double">5.190000057220459</d:BC_3MONTH>
<d:BC_6MONTH m:type="Edm.Double">5.3499999046325684</d:BC_6MONTH>
<d:BC_1YEAR m:type="Edm.Double">5.630000114440918</d:BC_1YEAR>
<d:BC_2YEAR m:type="Edm.Double">5.96999979019165</d:BC_2YEAR>
<d:BC_3YEAR m:type="Edm.Double">6.130000114440918</d:BC_3YEAR>
<d:BC_5YEAR m:type="Edm.Double">6.3000001907348633</d:BC_5YEAR>
<d:BC_7YEAR m:type="Edm.Double">6.4499998092651367</d:BC_7YEAR>
<d:BC_10YEAR m:type="Edm.Double">6.5399999618530273</d:BC_10YEAR>
<d:BC_20YEAR m:type="Edm.Double">6.8499999046325684</d:BC_20YEAR>
<d:BC_30YEAR m:type="Edm.Double">6.75</d:BC_30YEAR>
<d:BC_30YEARDISPLAY m:type="Edm.Double">0</d:BC_30YEARDISPLAY>
</m:properties>
</content>
</entry>
</feed>';
-涉及多個名稱空間。 一個xmlns
是所謂的默認名稱空間,而其他名稱空間都有一個前綴。 您可以使用任何喜歡的前綴,但是為了便於閱讀,我使用了與原始XML相同的前綴:
-以下代碼將演示如何直接讀取一些頂級元素,如何使用.nodes()
進入嵌套元素以及如何使用另一個.nodes()
進入相對的子節點。
WITH XMLNAMESPACES(DEFAULT 'http://www.w3.org/2005/Atom'
,'http://schemas.microsoft.com/ado/2007/08/dataservices/metadata' AS m
,'http://schemas.microsoft.com/ado/2007/08/dataservices' AS d
,'http://data.treasury.gov/Feed.svc/' AS base )
SELECT @xml.value('(/feed/title/text())[1]','varchar(100)') AS title
,@xml.value('(/feed/title/@type)[1]','varchar(100)') AS title_type
,@xml.value('(/feed/id/text())[1]','varchar(100)') AS id
,@xml.value('(/feed/updated/text())[1]','datetime') AS updated --type-safe
--pick more elements in top level
,ent.value('(id/text())[1]','varchar(100)') AS entry_id
--pick more elements from entry-level
,prp.value('(d:Id/text())[1]','int') AS Prop_id
--pick more elements below <m:properties>
FROM @xml.nodes('/feed/entry') A(ent)
CROSS APPLY A.ent.nodes('content/m:properties') B(prp);
-如果屬性可能事先未知,則可以在路徑中使用*
並返回通用的EAV列表:
WITH XMLNAMESPACES(DEFAULT 'http://www.w3.org/2005/Atom'
,'http://schemas.microsoft.com/ado/2007/08/dataservices/metadata' AS m
,'http://schemas.microsoft.com/ado/2007/08/dataservices' AS d
,'http://data.treasury.gov/Feed.svc/' AS base )
SELECT @xml.value('(/feed/title/text())[1]','varchar(100)') AS title
,@xml.value('(/feed/title/@type)[1]','varchar(100)') AS title_type
,@xml.value('(/feed/id/text())[1]','varchar(100)') AS id
,@xml.value('(/feed/updated/text())[1]','datetime') AS updated --type-safe
--pick more elements in top level
,ent.value('(id/text())[1]','varchar(100)') AS entry_id
--pick more elements from entry-level
,AllPrps.value('local-name(.)','varchar(100)') AS Prop_Name
,AllPrps.value('@m:type','varchar(100)') AS Prop_Value
,AllPrps.value('text()[1]','varchar(100)') AS Prop_Value
--pick more elements below <m:properties>
FROM @xml.nodes('/feed/entry') A(ent)
CROSS APPLY A.ent.nodes('content/m:properties/d:*') B(AllPrps)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.