Mam kod HTML zapisany w bazie danych i chcę go odczytać jako XML.
Moje kody:
http://rextester.com/RMEHO89992
To jest przykład kodu HTML, który mam:
<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>
a to jest przykład danych wyjściowych, których potrzebuję:
Category Selection Value
--------- --------- ------------
A Ab AD
A Ag AL
B Bb BD
B Bg BL
Muszę uzyskać wartość wewnątrz <h4>
znacznika jako Category
, pierwszy <span>
znacznik jako Zaznaczenie, a resztę wartości jako połączony ciąg.
Próbowałem następującego zapytania:
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)
i :
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)
Ale dostaje tylko pierwszą kategorię i nie łączy wszystkich wartości razem.
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
Może istnieć N kategorii, a wartości mogą, ale nie muszą znajdować się w <span>
tagach. Jak mogę uzyskać wszystkie kategorie z odpowiadającymi im wartościami? lub uzyskaj:
category h4 number
-------- -----------
A 1
B 2
- 1, średnia = h4 pierwsza, 2, średnia = h4 druga
ul number Selection Value
--------- --------- ------------
1 Ab AD
1 Ag AL
2 Bb BD
2 Bg BL
związek między liczbą ul kolumny a liczbą h4. Nie mogę.
sql-server
t-sql
xml
Armia Czerwona
źródło
źródło
AD AC
w pierwszym rzędzie w trzeciej kolumnie?Odpowiedzi:
Nie jest to do końca eleganckie, ale wydaje się, że wykonuje swoją pracę.
Który zwraca
Zakładam, że tego właśnie potrzebujesz, ponieważ żądana tabela wyników w pytaniu nie zwraca „reszty wartości jako łańcucha łączonego”
źródło
Za pomocą operatora
<<
i>>
można sprawdzić, czy węzeł znajduje się przed czy za innym węzłem w kolejności dokumentów. Połącz to z predykatem dotyczącym pozycji,[1]
aby uzyskać pierwsze wystąpienie również w kolejności dokumentów.rextester:
<<
i>>
nazywane są operatorami porównania kolejności węzłówJeśli masz taki fragment XML:
możesz pobrać wszystkie węzły przed pierwszym wystąpieniem
N3
tego zapytania:Wynik:
/*
da ci wszystkie węzły główne. To, co jest zamknięte,[]
to orzeczenie..
jest bieżącym węzłem i/N3[1]
jest pierwszym węzłem N3 w kolejności dokumentów na poziomie głównym. Tak więc z każdego węzła głównego otrzymujesz poprzedzające go węzłyN3
.Oto prawie to samo zapytanie, tylko ty dostajesz węzły następujące po pierwszym
N3
węźle:Aby uzyskać tylko pierwszy węzeł za pierwszym
N3
, dodaj predykat[1]
:źródło