Sql server 将XML解析到SQL Server表中,并将XHTML标记保留在XML元素中
这个问题是XML文件中有xhtml标记,请参见示例代码元素,当我运行XQuery时,它似乎去掉了标记,只保留了文本。我希望将示例代码的值存储在表中,与XML文件中的值完全相同。 非常感谢你的阅读Sql server 将XML解析到SQL Server表中,并将XHTML标记保留在XML元素中,sql-server,xml,Sql Server,Xml,这个问题是XML文件中有xhtml标记,请参见示例代码元素,当我运行XQuery时,它似乎去掉了标记,只保留了文本。我希望将示例代码的值存储在表中,与XML文件中的值完全相同。 非常感谢你的阅读 DECLARE @Xml XML = N' <Demonstrative_Examples xmlns:xhtml="http://www.w3.org/1999/xhtml">> <Demonstrative_Example>
DECLARE @Xml XML =
N'
<Demonstrative_Examples xmlns:xhtml="http://www.w3.org/1999/xhtml">>
<Demonstrative_Example>
<Intro_Text>This is the intro</Intro_Text>
<Example_Code Nature="bad">Example 1.1</Example_Code>
<Body_Text>Body 1.1</Body_Text>
<Example_Code> <xhtml:div>String sessionID = generateSessionId();<xhtml:br/>Cookie c = new Cookie("session_id", sessionID);<xhtml:br/>response.addCookie(c);</xhtml:div>
</Example_Code>
</Demonstrative_Example>
<Demonstrative_Example>
<Intro_Text>This is the 2nd intro</Intro_Text>
<Body_Text>Body 2.1</Body_Text>
<Example_Code Nature="Good">Example 2.1</Example_Code>
</Demonstrative_Example>
</Demonstrative_Examples>';
-- just to see
;WITH XMLNAMESPACES ('http://www.w3.org/1999/xhtml' as xhtml)
SELECT @xml.query('<root>
{
for $x in /Demonstrative_Examples/Demonstrative_Example
let $id := count(/Demonstrative_Examples/Demonstrative_Example[. << $x[1]]) + 1
for $y in $x/*[position() gt 1]
let $pos := count($x/*[. << $y[1]]) + 1
let $it := $x/*[local-name()="Intro_Text"]
return <r id="{$id}" pos="{$pos - 1}"
Intro_Text="{$it}"
Body_Text="{$y[local-name()="Body_Text"]/text()}"
Example_Code="{$y[local-name()="Example_Code"]}"
Nature="{$y[local-name()="Example_Code"]/@Nature}"></r>
}
</root>') AS xmldata;
-- real deal
;WITH rs AS
(
SELECT @xml.query('<root>
{
for $x in /Demonstrative_Examples/Demonstrative_Example
let $id := count(/Demonstrative_Examples/Demonstrative_Example[. << $x[1]]) + 1
for $y in $x/*[position() gt 1]
let $pos := count($x/*[. << $y[1]]) + 1
let $it := $x/*[local-name()="Intro_Text"]
return <r id="{$id}" pos="{$pos - 1}"
Intro_Text="{$it}"
Body_Text="{$y[local-name()="Body_Text"]/text()}"
Example_Code="{$y[local-name()="Example_Code"]/text()}"
Nature="{$y[local-name()="Example_Code"]/@Nature}"></r>
}
</root>') AS xmldata
)
SELECT c.value('@id', 'INT') AS [ID]
, c.value('@pos', 'INT') AS [Order]
, c.value('@Intro_Text', 'VARCHAR(30)') AS [Intro_Text]
, c.value('@Body_Text', 'VARCHAR(30)') AS [Body_Text]
, c.value('@Example_Code', 'VARCHAR(30)') AS [Example_Code]
, c.value('@Nature', 'VARCHAR(30)') AS [Nature]
FROM rs CROSS APPLY xmldata.nodes('/root/r') AS t(c);
这是结果集:
要在元素值为XHTML/XML时保留它,需要在源XML中使用CDATA部分。请看下面
我做了一些额外的修改:
注释掉名称空间声明。在这种情况下不需要它。
将@Example_代码大小增加为VARCHARMAX,以适应冗长的值。
SQL
DECLARE @Xml XML =
N'<Demonstrative_Examples xmlns:xhtml="http://www.w3.org/1999/xhtml">
<Demonstrative_Example>
<Intro_Text>This is the intro</Intro_Text>
<Example_Code Nature="bad">Example 1.1</Example_Code>
<Body_Text>Body 1.1</Body_Text>
<Example_Code><![CDATA[
<xhtml:div>String sessionID = generateSessionId();<xhtml:br/>Cookie c = new Cookie("session_id", sessionID);<xhtml:br/>response.addCookie(c);</xhtml:div>
]]>
</Example_Code>
</Demonstrative_Example>
<Demonstrative_Example>
<Intro_Text>This is the 2nd intro</Intro_Text>
<Body_Text>Body 2.1</Body_Text>
<Example_Code Nature="Good">Example 2.1</Example_Code>
</Demonstrative_Example>
</Demonstrative_Examples>';
-- just to see
--;WITH XMLNAMESPACES ('http://www.w3.org/1999/xhtml' as xhtml)
SELECT @xml.query('<root>
{
for $x in /Demonstrative_Examples/Demonstrative_Example
let $id := count(/Demonstrative_Examples/Demonstrative_Example[. << $x[1]]) + 1
let $it := $x/*[local-name()="Intro_Text"]
for $y in $x/*[position() gt 1]
let $pos := count($x/*[. << $y[1]]) + 1
return <r id="{$id}" pos="{$pos - 1}"
Intro_Text="{$it}"
Body_Text="{$y[local-name()="Body_Text"]/text()}"
Example_Code="{$y[local-name()="Example_Code"]}"
Nature="{$y[local-name()="Example_Code"]/@Nature}"></r>
}
</root>') AS xmldata;
-- real deal
;WITH rs AS
(
SELECT @xml.query('<root>
{
for $x in /Demonstrative_Examples/Demonstrative_Example
let $id := count(/Demonstrative_Examples/Demonstrative_Example[. << $x[1]]) + 1
let $it := $x/*[local-name()="Intro_Text"]
for $y in $x/*[position() gt 1]
let $pos := count($x/*[. << $y[1]]) + 1
return <r id="{$id}" pos="{$pos - 1}"
Intro_Text="{$it}"
Body_Text="{$y[local-name()="Body_Text"]/text()}"
Example_Code="{$y[local-name()="Example_Code"]/text()}"
Nature="{$y[local-name()="Example_Code"]/@Nature}"></r>
}
</root>') AS xmldata
)
SELECT c.value('@id', 'INT') AS [ID]
, c.value('@pos', 'INT') AS [Order]
, c.value('@Intro_Text', 'VARCHAR(30)') AS [Intro_Text]
, c.value('@Body_Text', 'VARCHAR(30)') AS [Body_Text]
, c.value('@Example_Code', 'VARCHAR(MAX)') AS [Example_Code]
, c.value('@Nature', 'VARCHAR(30)') AS [Nature]
FROM rs CROSS APPLY xmldata.nodes('/root/r') AS t(c);
declare @Xml XML =
N'
<Demonstrative_Examples xmlns:xhtml="http://www.w3.org/1999/xhtml">
<Demonstrative_Example>
<Intro_Text>This is the intro</Intro_Text>
<Example_Code Nature="Bad">Example 1.1</Example_Code>
<Body_Text>Body 1.1</Body_Text>
<Example_Code><xhtml:div>String sessionID = generateSessionId();<xhtml:br/>Cookie c = new Cookie("session_id", sessionID);<xhtml:br/>response.addCookie(c);</xhtml:div></Example_Code>
</Demonstrative_Example>
<Demonstrative_Example>
<Intro_Text>This is the 2nd intro</Intro_Text>
<Body_Text>Body 2.1</Body_Text>
<Example_Code Nature="Good">Example 2.1</Example_Code>
<e4>e4</e4>
<e5>e5</e5>
<e6>e6</e6>
<e7>e7</e7>
<e8>e8</e8>
<Example_Code Nature="Ugly">examplecode position9 <xhtml:div>String sessionID = generateSessionId();<xhtml:br/>Cookie c = new Cookie("session_id", sessionID);<xhtml:br/>response.addCookie(c);</xhtml:div></Example_Code>
</Demonstrative_Example>
</Demonstrative_Examples>';
select
s.example_order_id,
s.position_in_example,
case s.elementname when N'Intro_Text' then s.nodecontent end as IntroText,
case s.elementname when N'Example_Code' then s.nodecontent end as ExampleCode,
case s.elementname when N'Body_Text' then s.nodecontent end as BodyText,
case s.elementname when N'Example_Code' then s.attributenature end as ExampleNature
from
(
select
dense_rank() over(order by d.ex) as example_order_id,
row_number() over(partition by d.ex order by ex.el) as position_in_example,
ex.el.value('local-name(.)[1]', 'nvarchar(100)') as elementname,
ex.el.value('@Nature[1]', 'nvarchar(30)') as attributenature,
cast(ex.el.query('node()') as nvarchar(max)) as nodecontent
from @Xml.nodes('Demonstrative_Examples/Demonstrative_Example') as d(ex)
outer apply d.ex.nodes('*') as ex(el)
) as s
where s.elementname in (N'Intro_Text', N'Example_Code', N'Body_Text');