2013-04-25 16 views
5

Mamy system cms, który zapisuje bloki zawartości html w bazie danych serwera SQL. Znam nazwę tabeli i nazwę pola, w którym znajdują się bloki zawartości html. Niektóre html zawiera linki() do plików pdf. Oto fragment:Jak wyodrębnić nazwy plików z pola zawierającego treść HTML na serwerze sql?

<p>A deferred tuition payment plan, 
or view the <a href="/uploadedFiles/Tuition-Reimbursement-Deferred.pdf" 
target="_blank">list</a>.</p> 

Potrzebuję wyodrębnić nazwy plików pdf ze wszystkich takich bloków treści html. Na koniec muszę uzyskać listę:

Tuition-Reimbursement-Deferred.pdf 
Some-other-file.pdf 

wszystkich nazw plików PDF z tej dziedziny.

Każda pomoc jest doceniana. Dzięki.

UPDATE

Otrzymałem wiele odpowiedzi, bardzo dziękuję, ale zapomniałem wspomnieć, że nadal jesteśmy przy użyciu programu SQL Server 2000 tutaj. Musiało to zostać wykonane przy użyciu SQL SQL SQL.

+2

Czy wszyscy mają folder, który poprzedza nazwy pliku? –

+0

Czy musisz to zrobić w TSQL? Jest to bardzo słaby język do analizowania tekstu, a byłoby znacznie łatwiej w innym języku, który ma bibliotekę analizy parsowania HTML. – Pondlife

+0

Zgadzam się, to tylko szybkie opcje. W razie potrzeby użyję HTMLAgilityPack w moim kodzie C# do przeanalizowania zawartości. – monstro

Odpowiedz

1

No nie całkiem, ale to działa przy użyciu standardowego Transact-SQL:

SELECT CASE WHEN CHARINDEX('.pdf', html) > 0 
      THEN SUBSTRING(
        html, 
        CHARINDEX('.pdf', html) - 
        PATINDEX(
         '%["/]%', 
         REVERSE(SUBSTRING(html, 0, CHARINDEX('.pdf', html)))) + 1, 
        PATINDEX(
         '%["/]%', 
         REVERSE(SUBSTRING(html, 0, CHARINDEX('.pdf', html)))) + 3) 
      ELSE NULL 
     END AS filename 
FROM mytable 

można rozwinąć listę znaków ograniczających przed nazwą pliku z ["/] (co odpowiada albo znak cudzysłowu lub ukośnik) Jeśli lubisz.

Zobacz SQL Fiddle demo

+0

Wspaniale, zapomniałem wspomnieć, że mamy tutaj SQL 2000, więc to podejście Prace !! Wielkie dzięki. – monstro

3

Tworzenie tej funkcji:

create function dbo.extract_filenames_from_a_tags (@s nvarchar(max)) 
returns @res table (pdf nvarchar(max)) as 
begin 
-- assumes there are no single quotes or double quotes in the PDF filename 
declare @i int, @j int, @k int, @tmp nvarchar(max); 
set @i = charindex(N'.pdf', @s); 
while @i > 0 
begin 
    select @tmp = left(@s, @i+3); 
    select @j = charindex('/', reverse(@tmp)); -- directory delimiter 
    select @k = charindex('"', reverse(@tmp)); -- start of href 
    if @j = 0 or (@k > 0 and @k < @j) set @j = @k; 
    select @k = charindex('''', reverse(@tmp)); -- start of href (single-quote*) 
    if @j = 0 or (@k > 0 and @k < @j) set @j = @k; 
    insert @res values (substring(@tmp, len(@tmp)[email protected]+2, len(@tmp))); 
    select @s = stuff(@s, 1, @i+4, ''); -- remove up to ".pdf" 
    set @i = charindex(N'.pdf', @s); 
end 
return 
end 
GO 

Demo na temat korzystania z tej funkcji:

declare @t table (html varchar(max)); 
insert @t values 
    (' 
<p>A deferred tuition payment plan, 
or view the <a href="/uploadedFiles/Tuition-Reimbursement-Deferred.pdf" 
target="_blank">list</a>.</p>'), 
    (' 
<p>A deferred tuition payment plan, 
or view the <a href="Two files here-Reimbursement-Deferred.pdf" 
target="_blank">list</a>.</p>And I use single quotes 
    <a href=''/look/path/The second file.pdf'' 
target="_blank">list</a>'); 

select t.*, p.pdf 
from @t t 
cross apply dbo.extract_filenames_from_a_tags(html) p; 

Wyniki:

|HTML     |          PDF | 
-------------------------------------------------------------------- 
|<p>A deferred tui.... |  Tuition-Reimbursement-Deferred.pdf | 
|<p>A deferred tui.... | Two files here-Reimbursement-Deferred.pdf | 
|<p>A deferred tui.... |      The second file.pdf | 

SQL Fiddle Demo

+1

To jest niesamowita funkcja. –

+0

Wielkie dzięki, działa idealnie, ale zapomniałem wspomnieć, że nadal używamy tutaj SQL Server 2000, a ten kod nie będzie działał na SQL 2000. – monstro

1

Jak o leczeniu tej HTML jako XML?

declare @t table (html varchar(max)); 
insert @t 
    select ' 
    <p>A deferred tuition payment plan, 
    or view the <a href="/uploadedFiles/Tuition-Reimbursement-Deferred.pdf" 
    target="_blank">list</a>.</p>' 
    union all 
    select ' 
    <p>A deferred tuition payment plan, 
    or view the <a href="Two files here-Reimbursement-Deferred.pdf" 
    target="_blank">list</a>.</p>And I use single quotes 
     <a href=''/look/path/The second file.pdf'' 
    target="_blank">list</a>' 

select [filename] = reverse(left(reverse('/'+p.n.value('@href', 'varchar(100)')), charindex('/',reverse('/'+p.n.value('@href', 'varchar(100)')), 1) - 1)) 
from ( select cast(html as xml) 
      from @t 
     ) x(doc) 
cross 
apply doc.nodes('//a') p(n); 

Wyniki:

filename 
--------------------------------------------------------------- 
Tuition-Reimbursement-Deferred.pdf 
Two files here-Reimbursement-Deferred.pdf 
The second file.pdf 
1

próbować ten jeden -

DECLARE @XML XML = 
'<p>A deferred tuition payment plan, 
or view the <a href="/uploadedFiles/Tuition-Reimbursement-Deferred.pdf" 
target="_blank">list</a>.</p>' 

SELECT 
     ref_text = t.p.value('./a[1]', 'NVARCHAR(50)') 
    , ref_filename = REVERSE(
         LEFT(REVERSE(t.p.value('./a[1]/@href', 'NVARCHAR(50)')), 
         CHARINDEX('/',REVERSE(t.p.value('./a[1]/@href', 'NVARCHAR(50)')), 1) - 1)) 
FROM @XML.nodes('/p') t(p) 
+0

Wielkie dzięki, ale zapomniałem wspomnieć, że nadal używamy tutaj SQL Server 2000 i nie ma on typu danych XML :( – monstro