[英]Parse text and special characters from SQL Server
我在使用 SQL 服務器中的 XML 中的特殊字符解析文本時遇到問題。
假設我有一個 XML 文件Sample.xml
,其中包含以下數據:
<People>
<Person FirstName="Adam"
LastName="Smith"
Age="44"
Weight="178">
<Texts>
<Text Country="US"
Language="EN"
TextType="1"><div>First sentence to retrieve.</div></Text>
<Text Country="GB"
Language="EN"
TextType="2"><div>Second sentence to retrieve.</div></Text>
</Texts>
</Person>
</People>
我准備了以下 SQL 腳本,它可以解析除了<TextType>
屬性中的兩個句子之外的所有內容:
DECLARE @x XML
SELECT @x = f FROM OPENROWSET(BULK 'C:\Sample.xml', single_blob) AS C(f)
DECLARE @hdoc int
EXEC sp_xml_preparedocument @hdoc OUTPUT, @x
SELECT * FROM OPENXML (@hdoc, '/People/Person/Texts/Text')
WITH (
FirstName varchar(max) '../../@FirstName'
, LastName varchar(max) '../../@LastName'
, Age varchar(max) '../../@Age'
, [Weight] varchar(max) '../../@Weight'
, Country varchar(max) '@Country'
, [Language] varchar(max) '@Language'
, TextType varchar(max) '@TextType'
)
EXEC sp_xml_removedocument @hdoc
你能幫我添加上面提到的句子嗎?
OPENXML
是舊的並且基本上已被棄用,它有很多問題。
您應該使用較新的 XQuery 函數.nodes
和.value
來檢索數據。
您的主要問題是您將 XML 作為字符串存儲在另一個 XML 中。 您需要將其檢索為nvarchar(max)
,然后使用TRY_CONVERT
進行轉換。
SELECT
FirstName = x1.Person.value('@FirstName', 'varchar(100)'),
LastName = x1.Person.value('@LastName' , 'varchar(100)'),
Age = x1.Person.value('@Age' , 'int'),
Weight = x1.Person.value('@Weight' , 'decimal(9,5)'),
Country = x2.Text.value('@Country' , 'char(2)'),
[Language] = x2.Text.value('@Language', 'char(2)'),
TextType = x2.Text.value('@TextType', 'int'),
value = v.InnerXml.value('(div/text())[1]','nvarchar(max)')
FROM @x.nodes('People/Person') x1(Person)
CROSS APPLY x1.Person.nodes('Texts/Text') x2(Text)
CROSS APPLY (VALUES( TRY_CONVERT(xml, x2.Text.value('text()[1]','nvarchar(max)')) )) v(InnerXml);
請注意對.nodes
的兩次調用的方式,一個饋入下一個。
您甚至可以直接從OPENROWSET
輸入
SELECT
FirstName = x1.Person.value('@FirstName', 'varchar(100)'),
LastName = x1.Person.value('@LastName' , 'varchar(100)'),
Age = x1.Person.value('@Age' , 'int'),
Weight = x1.Person.value('@Weight' , 'decimal(9,5)'),
Country = x2.Text.value('@Country' , 'char(2)'),
[Language] = x2.Text.value('@Language', 'char(2)'),
TextType = x2.Text.value('@TextType', 'int'),
value = v.InnerXml.value('(div/text())[1]','nvarchar(max)')
FROM OPENROWSET(BULK 'C:\Sample.xml', single_blob) AS C(f)
CROSS APPLY (VALUES( TRY_CONVERT(xml, C.f) )) C2(AsXml)
CROSS APPLY C2.AsXml.nodes('People/Person') x1(Person)
CROSS APPLY x1.Person.nodes('Texts/Text') x2(Text)
CROSS APPLY (VALUES( TRY_CONVERT(xml, x2.Text.value('text()[1]','nvarchar(max)')) )) v(InnerXml);
我建議您修復生成此 XML 的任何內容,理想情況下,您將通過內部 XML 而不對其進行字符串化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.