Red*_*rmy 11 xml sql-server t-sql
我在数据库中存储了 HTML 代码,我想将其作为 XML 读取。
我的代码:
http://rextester.com/RMEHO89992
这是我拥有的 HTML 代码示例:
<div>
<section>
<h4>
<span> A </span>
</h4>
<ul>
<li>
<span> Ab</span>
AD
<span> AC </span>
</li>
<li>
<span> Ag</span>
<span> AL </span>
</li>
</ul>
<h4>
<span> B </span>
</h4>
<ul>
<li>
<span> Bb</span>
BD
<span> BC </span>
</li>
<li>
<span> Bg</span>
<span> BL </span>
</li>
</ul>
</section>
</div>
Run Code Online (Sandbox Code Playgroud)
这是我需要的输出示例:
Category Selection Value
--------- --------- ------------
A Ab AD
A Ag AL
B Bb BD
B Bg BL
Run Code Online (Sandbox Code Playgroud)
我需要将<h4>标签内的值作为 a Category,第一个<span>标签作为 Selection ,其余的值作为连接字符串。
我试过以下查询:
SELECT
( isnull(t.v.value('(h4/span/span[1]/text())[1]','nvarchar(max)'),'')
+ isnull(t.v.value('(h4/span/text())[1]','nvarchar(max)'),'')
+ isnull(t.v.value('(h4/span/span[2]/text())[2]','nvarchar(max)'),'')
) AS [Category],
( isnull(c.g.value('(span[1]/text())[1]','nvarchar(max)'),'')
+ isnull(c.g.value('(span[1]/span/text())[1]','nvarchar(max)'),'')
+ isnull(c.g.value('(span[1]/text())[2]','nvarchar(max)'),'')
) AS [Selection],
( isnull(c.g.value('(span[2]/text())[1]','nvarchar(max)'),'')
+ isnull(c.g.value('(span[2]/span/text())[1]','nvarchar(max)'),'')
+ isnull(c.g.value('(span[2]/text())[2]','nvarchar(max)'),'')
) AS [Value]
FROM @htmlXML.nodes('div/section') as t(v)
CROSS APPLY t.v.nodes('./ul/li') AS c(g)
Run Code Online (Sandbox Code Playgroud)
和:
SELECT
t.v.value('.','nvarchar(max)')
,
--( isnull(t.v.value('(h4/span/span[1]/text())[1]','nvarchar(max)'),'')+isnull(t.v.value('(h4/span/text())[1]','nvarchar(max)'),'')+isnull(t.v.value('(h4/span/span[2]/text())[2]','nvarchar(max)'),''))AS [Category],
( isnull(c.g.value('(span[1]/text())[1]','nvarchar(max)'),'')+isnull(c.g.value('(span[1]/span/text())[1]','nvarchar(max)'),'')+isnull(c.g.value('(span[1]/text())[2]','nvarchar(max)'),''))AS [Selection]
,
( isnull(c.g.value('(span[2]/text())[1]','nvarchar(max)'),'')+isnull(c.g.value('(span[2]/span/text())[1]','nvarchar(max)'),'')+isnull(c.g.value('(span[2]/text())[2]','nvarchar(max)'),''))AS [Value]
FROM @htmlXML.nodes('div/section/h4/span') as t(v)
CROSS APPLY @htmlXML.nodes('div/section/ul/li') AS c(g)
Run Code Online (Sandbox Code Playgroud)
但它只得到第一个类别,并没有得到所有的值。
Category Selection Value
--------- --------- ------------
A Ab AC
B Ab AC
A Ag AL
B Ag AL
A Bb BC
B Bb BC
A Bg BL
B Bg BL
Run Code Online (Sandbox Code Playgroud)
可以有 N 个类别,值可能在也可能不在<span>标签内。如何获得所有类别及其相应的值?或得到:
category h4 number
-------- -----------
A 1
B 2
Run Code Online (Sandbox Code Playgroud)
- 1 ,mean = h4 第一 , 2 ,mean = h4 第二
ul number Selection Value
--------- --------- ------------
1 Ab AD
1 Ag AL
2 Bb BD
2 Bg BL
Run Code Online (Sandbox Code Playgroud)
列 ul 编号和 h4 编号之间的关系。我不能。
Mik*_*son 14
我正在尝试在节点
h4和ul.
您可以使用<<and>>运算符来检查一个节点是在文档顺序中的另一个节点之前还是之后。将其与位置的谓词结合,[1], 以获取文档顺序中的第一次出现。
select H4.X.value('(span/text())[1]', 'varchar(10)') as Section,
UL.X.query('.') as UL
from @X.nodes('/div/section/h4') as H4(X)
cross apply H4.X.nodes('(let $h4 := . (: Save current h4 node :)
return /div/section/ul[$h4 << .])[1]') as UL(X);
Run Code Online (Sandbox Code Playgroud)
<<并>>称为节点顺序比较运算符
如果您有这样的 XML 片段:
<N1>1</N1>
<N2>2</N2>
<N3>3</N3>
<N4>4</N4>
<N5>5</N5>
Run Code Online (Sandbox Code Playgroud)
您可以N3使用此查询在第一次出现之前获取所有节点:
select @X.query('/*[. << /N3[1]]');
Run Code Online (Sandbox Code Playgroud)
结果:
<N1>1</N1>
<N2>2</N2>
Run Code Online (Sandbox Code Playgroud)
/*会给你所有的根节点。包含在其中的[]是谓词。.是当前节点,并且/N3[1]是根级别文档顺序中的第一个 N3 节点。因此,您可以从每个根节点获得在N3.
这是几乎相同的查询,只有你的节点遵循的第一N3点:
select @X.query('/*[. >> /N3[1]]');
Run Code Online (Sandbox Code Playgroud)
<N4>4</N4>
<N5>5</N5>
Run Code Online (Sandbox Code Playgroud)
要仅获取第一个节点之后的第一个N3节点,请添加谓词[1]:
select @X.query('/*[. >> /N3[1]][1]');
Run Code Online (Sandbox Code Playgroud)
<N4>4</N4>
Run Code Online (Sandbox Code Playgroud)
这并不完全优雅,但似乎可以完成这项工作。
DECLARE @X XML = REPLACE(REPLACE(@S, '<h4>', '<foo><h4>'), '</ul>', '</ul></foo>')
SELECT Category = x.value('../../h4[1]/span[1]', 'varchar(10)'),
Selection = x.value('descendant-or-self::text()[1]', 'varchar(10)'),
Value = REPLACE(
REPLACE(
REPLACE(
LTRIM(
RTRIM(
REPLACE(
REPLACE(
CAST(x.x.query('fn:data(descendant-or-self::text()[fn:position() > 1])') AS VARCHAR(MAX))
, char(10), '')
, char(13), '')
)
)
, ' ', ' |')
, '| ', '')
, '|', '')
FROM @X.nodes('div/section/foo/ul/li') x(x)
ORDER BY Category,
Selection
Run Code Online (Sandbox Code Playgroud)
+----------+-----------+-------+
| Category | Selection | Value |
+----------+-----------+-------+
| A | Ab | AD AC |
| A | Ag | AL |
| B | Bb | BD BC |
| B | Bg | BL |
+----------+-----------+-------+
Run Code Online (Sandbox Code Playgroud)
我假设这是您想要的,因为问题中所需的结果表不会返回“其余值作为连接字符串”
| 归档时间: |
|
| 查看次数: |
3855 次 |
| 最近记录: |